@@ -963,7 +963,49 @@ WORD* flint::gcd_mpoly(PHEAD const WORD *a, const WORD *b, const WORD must_fit_t
963963		Terminate (-1 );
964964	}
965965
966- 	fmpz_mpoly_gcd (gcd, pa, pb, ctx);
966+ 	//  poly returns pa if pa == pb, regardless of the lcoeff sign
967+ 	if  ( fmpz_mpoly_equal (pa, pb, ctx) ) {
968+ 		fmpz_mpoly_set (gcd, pa, ctx);
969+ 	}
970+ 	else  {
971+ 		//  We need some gymnastics to have the same sign conventions as the poly class. It takes the
972+ 		//  integer or univar content out of a,b, with the convention that the content sign matches
973+ 		//  the lcoeff sign. Since FORM has already taken out the content, we are left with +-1. In
974+ 		//  Flint, the content always has a positive sign so here we should find +1. Check this:
975+ 		fmpz_mpoly_t  tmp;
976+ 		fmpz_mpoly_init (tmp, ctx);
977+ 		fmpz_mpoly_term_content (tmp, pa, ctx);
978+ 		if  ( fmpz_mpoly_is_one (tmp, ctx) != 1  ) {
979+ 			MLOCK (ErrorMessageLock);
980+ 			MesPrint (" flint::gcd_mpoly: error: content of 1st arg != 1" 
981+ 			MUNLOCK (ErrorMessageLock);
982+ 			Terminate (-1 );
983+ 		}
984+ 		fmpz_mpoly_term_content (tmp, pb, ctx);
985+ 		if  ( fmpz_mpoly_is_one (tmp, ctx) != 1  ) {
986+ 			MLOCK (ErrorMessageLock);
987+ 			MesPrint (" flint::gcd_mpoly: error: content of 2nd arg != 1" 
988+ 			MUNLOCK (ErrorMessageLock);
989+ 			Terminate (-1 );
990+ 		}
991+ 		fmpz_mpoly_clear (tmp, ctx);
992+ 
993+ 		//  The poly class now divides the content out of a,b so that they have a positive lcoeff.
994+ 		//  Then it muliplies the final gcd (which is given a positive lcoeff also) by
995+ 		//  gcd(cont a, cont b). There it has gcd(1,1) = gcd(-1,1) = gcd(1,-1) = 1, and
996+ 		//  gcd(-1,-1) = -1 (because of the pa==pb early return). So: if both input polys have a
997+ 		//  negative lcoeff, we will flip the sign in the final result.
998+ 		bool  flip_sign = 0 ;
999+ 		if  ( ( fmpz_sgn (fmpz_mpoly_term_coeff_ref (pa, 0 , ctx)) == -1  ) &&
1000+ 			( fmpz_sgn (fmpz_mpoly_term_coeff_ref (pb, 0 , ctx)) == -1  ) ) {
1001+ 			flip_sign = 1 ;
1002+ 		}
1003+ 
1004+ 		fmpz_mpoly_gcd (gcd, pa, pb, ctx);
1005+ 		if  ( flip_sign ) {
1006+ 			fmpz_mpoly_neg (gcd, gcd, ctx);
1007+ 		}
1008+ 	}
9671009
9681010	//  This is freed by the caller
9691011	WORD *res;
@@ -1030,7 +1072,34 @@ WORD* flint::gcd_poly(PHEAD const WORD *a, const WORD *b, const WORD must_fit_te
10301072		Terminate (-1 );
10311073	}
10321074
1033- 	fmpz_poly_gcd (gcd, pa, pb);
1075+ 	//  poly returns pa if pa == pb, regardless of the lcoeff sign
1076+ 	if  ( fmpz_poly_equal (pa, pb) ) {
1077+ 		fmpz_poly_set (gcd, pa);
1078+ 	}
1079+ 	else  {
1080+ 		//  Here, we don't have to make any sign flips like the mpoly case, because poly's
1081+ 		//  integer_gcd(1,1) = integer_gcd(-1,1) = integer_gcd(1,-1) = integer_gcd(-1,-1) = +1.
1082+ 		//  Still, verify that the content is 1:
1083+ 		fmpz_t  tmp;
1084+ 		fmpz_init (tmp);
1085+ 		fmpz_poly_content (tmp, pa);
1086+ 		if  ( fmpz_is_one (tmp) != 1  ) {
1087+ 			MLOCK (ErrorMessageLock);
1088+ 			MesPrint (" flint::gcd_poly: error: content of 1st arg != 1" 
1089+ 			MUNLOCK (ErrorMessageLock);
1090+ 			Terminate (-1 );
1091+ 		}
1092+ 		fmpz_poly_content (tmp, pb);
1093+ 		if  ( fmpz_is_one (tmp) != 1  ) {
1094+ 			MLOCK (ErrorMessageLock);
1095+ 			MesPrint (" flint::gcd_poly: error: content of 2nd arg != 1" 
1096+ 			MUNLOCK (ErrorMessageLock);
1097+ 			Terminate (-1 );
1098+ 		}
1099+ 		fmpz_clear (tmp);
1100+ 
1101+ 		fmpz_poly_gcd (gcd, pa, pb);
1102+ 	}
10341103
10351104	//  This is freed by the caller
10361105	WORD *res;
0 commit comments