From 4175f846fe81a51c081c2c316fde3d47f149ae87 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Tue, 26 Nov 2024 23:11:02 -0500 Subject: [PATCH 1/4] Add extended GCD function for integers to interpreter Wraps GMP's mpz_gcdext --- M2/Macaulay2/d/actors3.d | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/M2/Macaulay2/d/actors3.d b/M2/Macaulay2/d/actors3.d index 65902ee3d08..6c8ad23dc70 100644 --- a/M2/Macaulay2/d/actors3.d +++ b/M2/Macaulay2/d/actors3.d @@ -2362,6 +2362,29 @@ gcd(x:Expr,y:Expr):Expr := ( gcdfun(e:Expr):Expr := accumulate(plus0,plus1,gcd,e); setupfun("gcd0",gcdfun); +gcdCoefficients(e:Expr):Expr := ( + when e + is a:Sequence do ( + if length(a) == 2 then ( + when a.0 + is x:ZZcell do ( + when a.1 + is y:ZZcell do ( + g := newZZmutable(); + s := newZZmutable(); + t := newZZmutable(); + Ccode(void, "mpz_gcdext(", g, ", ", s, ", ", t, ", ", x.v, + ", ", y.v, ")"); + list( + Expr(ZZcell(moveToZZandclear(g))), + Expr(ZZcell(moveToZZandclear(s))), + Expr(ZZcell(moveToZZandclear(t))))) + else WrongArgZZ(2)) + else WrongArgZZ(1)) + else WrongNumArgs(2)) + else WrongNumArgs(2)); +setupfun("gcdCoefficients0", gcdCoefficients); + binomial(e:Expr):Expr := ( when e is a:Sequence do ( From ad88a24aaefc82d1c045c99b4848bb0f1730dfc3 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Tue, 26 Nov 2024 23:11:28 -0500 Subject: [PATCH 2/4] Use GMP function for gcdCoefficients(ZZ, ZZ) --- M2/Macaulay2/m2/quotient.m2 | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/M2/Macaulay2/m2/quotient.m2 b/M2/Macaulay2/m2/quotient.m2 index 31764634be3..b7545f8fafc 100644 --- a/M2/Macaulay2/m2/quotient.m2 +++ b/M2/Macaulay2/m2/quotient.m2 @@ -21,18 +21,7 @@ saturate = method(Options => options quotient) -- moved to packages/Saturation.m2 in October 2020 annihilator = method(Options => {Strategy => null}) -- Intersection or Quotient -gcdCoefficients(ZZ,ZZ) := (a,b) -> ( - m := {a,1,0}; - n := {b,0,1}; - if a<0 then m=-m; - if b<0 then n=-n; - if a>b then (k :=m;m=n;n=k); - while m#0 > 0 do ( - t := n#0 // m#0; - n = n - apply(m,y -> t * y); - (k=m;m=n;n=k); - ); - n); +gcdCoefficients(ZZ,ZZ) := gcdCoefficients0 mod = (i,n) -> i * 1_(ZZ/n) From be05d9abd8367e703c5ff2f6ec692058345f4979 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Wed, 27 Nov 2024 12:16:10 -0500 Subject: [PATCH 3/4] Allow mixing ZZ & RingElement inputs in gcdCoefficients This matches the behavior of gcd --- M2/Macaulay2/m2/factor.m2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/M2/Macaulay2/m2/factor.m2 b/M2/Macaulay2/m2/factor.m2 index e8e275f5fac..97368b5b22d 100644 --- a/M2/Macaulay2/m2/factor.m2 +++ b/M2/Macaulay2/m2/factor.m2 @@ -38,6 +38,8 @@ gcd(RingElement,RingElement) := RingElement => (r,s) -> ( s // a)) else notImplemented())) +gcdCoefficients(ZZ, RingElement) := (r, s) -> gcdCoefficients(r_(ring s), s) +gcdCoefficients(RingElement, ZZ) := (r, s) -> gcdCoefficients(r, s_(ring r)) gcdCoefficients(RingElement,RingElement) := (f,g) -> ( -- ?? R := ring f; if R =!= ring g then error "expected elements of the same ring"; From 236a2ae0dd2abb3634f3f517dc78e15335aa7643 Mon Sep 17 00:00:00 2001 From: Doug Torrance Date: Wed, 27 Nov 2024 12:16:49 -0500 Subject: [PATCH 4/4] Improve gcdCoefficients docs Convert to SimpleDoc, add new methods, and provide examples --- .../packages/Macaulay2Doc/doc_arithmetic.m2 | 44 +++++++++++++++---- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/M2/Macaulay2/packages/Macaulay2Doc/doc_arithmetic.m2 b/M2/Macaulay2/packages/Macaulay2Doc/doc_arithmetic.m2 index 3ef74852aa5..2ffe60fe7d5 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/doc_arithmetic.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/doc_arithmetic.m2 @@ -72,15 +72,41 @@ document { "conjugate 3" } } -document { - Key => {gcdCoefficients,(gcdCoefficients, RingElement, RingElement),(gcdCoefficients, ZZ, ZZ)}, - Headline => "gcd with coefficients", - TT "gcdCoefficients(a,b)", " -- returns ", TT "{d,r,s}", " so that - ", TT"a*r + b*s", " is the greatest common divisor ", TT "d", " of ", TT "a", " - and ", TT "b", ".", - PARA{}, - "Works for integers or elements of polynomial rings in onve variable.", - SeeAlso => "gcd"} + +doc /// + Key + gcdCoefficients + (gcdCoefficients, RingElement, RingElement) + (gcdCoefficients, RingElement, ZZ) + (gcdCoefficients, ZZ, RingElement) + (gcdCoefficients, ZZ, ZZ) + Headline + greatest common divisor with coefficients + Usage + gcdCoefficients(a, b) + Inputs + a:{RingElement, ZZ} + b:{RingElement, ZZ} + Description + Text + This returns a list of the form @CODE "{d, r, s}"@ so that $d = ar + bs$ + and $d=\gcd(a, b)$. + + It works for integers or elements of polynomial rings in one variable. + Example + gcdCoefficients(46, 240) + gcd(46, 240) + 46 * 47 + 240 * (-9) + R = ZZ/2[x] + f = x^8 + x^4 + x^3 + x + 1 + g = x^6 + x^4 + x + 1 + gcdCoefficients(f, g) + gcd(f, g) + f * (x^5 + x^4 + x^3 + x^2 + 1) + g * (x^7 + x^6 + x^3 + x) + SeeAlso + gcd +/// + document { Key => mod, Headline => "reduce modulo an integer",