Changeset 4a05ed in git
- Timestamp:
- Jul 28, 2011, 10:18:43 AM (12 years ago)
- Branches:
- (u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'a800fe4b3e9d37a38c5a10cc0ae9dfa0c15a4ee6')
- Children:
- 9b2c8a555e7d7ece9071e76ad8ec4d78ea3b9f01
- Parents:
- 41b5c0dddd342e89c06e4c8949e8da57bf5031ca
- Location:
- factory
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
factory/algext.cc
r41b5c0 r4a05ed 825 825 { 826 826 s*=inv; 827 s= reduce (s, M); 827 828 t*=inv; 829 t= reduce (t, M); 828 830 result *= inv; // monify result 831 result= reduce (result, M); 829 832 return; 830 833 } … … 946 949 result = reduce(result, M); 947 950 divides = true; 951 } 952 953 void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail ) 954 { 955 // F, G are univariate polynomials (i.e. they have exactly one polynomial variable) 956 // F and G must have the same level AND level > 0 957 // we try to calculate gcd(f,g) = s*F + t*G 958 // if a zero divisor is encontered, 'fail' is set to one 959 Variable a, b; 960 if( !hasFirstAlgVar(F,a) && !hasFirstAlgVar(G,b) ) // note lazy evaluation 961 { 962 result = extgcd( F, G, s, t ); // no zero divisors possible 963 return; 964 } 965 if( b.level() > a.level() ) 966 a = b; 967 // here: a is the biggest alg. var in F and G 968 CanonicalForm M = getMipo(a); 969 CanonicalForm P; 970 if( degree(F) > degree(G) ) 971 { 972 P=F; result=G; s=0; t=1; 973 } 974 else 975 { 976 P=G; result=F; s=1; t=0; 977 } 978 CanonicalForm inv, rem, q, u, v; 979 // here: degree(P) >= degree(result) 980 while(true) 981 { 982 tryInvert( Lc(result), M, inv, fail ); 983 if(fail) 984 return; 985 // here: Lc(result) is invertible modulo M 986 q = Lc(P)*inv * power( P.mvar(), degree(P)-degree(result) ); 987 rem = P - q*result; 988 // here: s*F + t*G = result 989 if( rem.isZero() ) 990 { 991 s*=inv; 992 t*=inv; 993 result *= inv; // monify result 994 return; 995 } 996 P=result; 997 result=rem; 998 rem=u-q*s; 999 u=s; 1000 s=rem; 1001 rem=v-q*t; 1002 v=t; 1003 t=rem; 1004 } 948 1005 } 949 1006 … … 1068 1125 } 1069 1126 1070 1071 void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail )1072 {1073 // F, G are univariate polynomials (i.e. they have exactly one polynomial variable)1074 // F and G must have the same level AND level > 01075 // we try to calculate gcd(f,g) = s*F + t*G1076 // if a zero divisor is encontered, 'fail' is set to one1077 Variable a, b;1078 if( !hasFirstAlgVar(F,a) && !hasFirstAlgVar(G,b) ) // note lazy evaluation1079 {1080 result = extgcd( F, G, s, t ); // no zero divisors possible1081 return;1082 }1083 if( b.level() > a.level() )1084 a = b;1085 // here: a is the biggest alg. var in F and G1086 CanonicalForm M = getMipo(a);1087 CanonicalForm P;1088 if( degree(F) > degree(G) )1089 {1090 P=F; result=G; s=0; t=1;1091 }1092 else1093 {1094 P=G; result=F; s=1; t=0;1095 }1096 CanonicalForm inv, rem, q, u, v;1097 // here: degree(P) >= degree(result)1098 while(true)1099 {1100 tryInvert( Lc(result), M, inv, fail );1101 if(fail)1102 return;1103 // here: Lc(result) is invertible modulo M1104 q = Lc(P)*inv * power( P.mvar(), degree(P)-degree(result) );1105 rem = P - q*result;1106 // here: s*F + t*G = result1107 if( rem.isZero() )1108 {1109 s*=inv;1110 t*=inv;1111 result *= inv; // monify result1112 return;1113 }1114 P=result;1115 result=rem;1116 rem=u-q*s;1117 u=s;1118 s=rem;1119 rem=v-q*t;1120 v=t;1121 t=rem;1122 }1123 } -
factory/algext.h
r41b5c0 r4a05ed 15 15 bool hasFirstAlgVar( const CanonicalForm &, Variable & ); 16 16 void tryBrownGCD( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm & M, CanonicalForm & result, bool & fail, bool topLevel= true ); 17 void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail );17 void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm& M, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail ); 18 18 int * leadDeg(const CanonicalForm & f, int *degs); 19 19 bool isLess(int *a, int *b, int lower, int upper); -
factory/facHensel.cc
r41b5c0 r4a05ed 28 28 #include "fac_util.h" 29 29 #include "cf_algorithm.h" 30 #include "cf_primes.h" 30 31 31 32 #ifdef HAVE_NTL 32 33 #include <NTL/lzz_pEX.h> 33 34 #include "NTLconvert.h" 35 36 static 37 CFList productsNTL (const CFList& factors, const CanonicalForm& M) 38 { 39 zz_p::init (getCharacteristic()); 40 zz_pX NTLMipo= convertFacCF2NTLzzpX (M); 41 zz_pE::init (NTLMipo); 42 zz_pEX prod; 43 vec_zz_pEX v; 44 v.SetLength (factors.length()); 45 int j= 0; 46 for (CFListIterator i= factors; i.hasItem(); i++, j++) 47 { 48 if (i.getItem().inCoeffDomain()) 49 v[j]= to_zz_pEX (to_zz_pE (convertFacCF2NTLzzpX (i.getItem()))); 50 else 51 v[j]= convertFacCF2NTLzz_pEX (i.getItem(), NTLMipo); 52 } 53 CFList result; 54 Variable x= Variable (1); 55 for (int j= 0; j < factors.length(); j++) 56 { 57 int k= 0; 58 set(prod); 59 for (int i= 0; i < factors.length(); i++, k++) 60 { 61 if (k == j) 62 continue; 63 prod *= v[i]; 64 } 65 result.append (convertNTLzz_pEX2CF (prod, x, M.mvar())); 66 } 67 return result; 68 } 69 70 static 71 void tryDiophantine (CFList& result, const CanonicalForm& F, 72 const CFList& factors, const CanonicalForm& M, bool& fail) 73 { 74 ASSERT (M.isUnivariate(), "expected univariate poly"); 75 76 CFList bufFactors= factors; 77 bufFactors.removeFirst(); 78 bufFactors.insert (factors.getFirst () (0,2)); 79 CanonicalForm inv, leadingCoeff= Lc (F); 80 CFListIterator i= bufFactors; 81 if (bufFactors.getFirst().inCoeffDomain()) 82 { 83 if (i.hasItem()) 84 i++; 85 } 86 for (; i.hasItem(); i++) 87 { 88 tryInvert (Lc (i.getItem()), M, inv ,fail); 89 if (fail) 90 return; 91 i.getItem()= reduce (i.getItem()*inv, M); 92 } 93 bufFactors= productsNTL (bufFactors, M); 94 95 CanonicalForm buf1, buf2, buf3, S, T; 96 i= bufFactors; 97 if (i.hasItem()) 98 i++; 99 buf1= bufFactors.getFirst(); 100 buf2= i.getItem(); 101 tryExtgcd (buf1, buf2, M, buf3, S, T, fail); 102 if (fail) 103 return; 104 result.append (S); 105 result.append (T); 106 if (i.hasItem()) 107 i++; 108 for (; i.hasItem(); i++) 109 { 110 buf1= i.getItem(); 111 CanonicalForm bb= buf3; 112 tryExtgcd (buf3, buf1, M, buf3, S, T, fail); 113 if (fail) 114 return; 115 CFListIterator k= factors; 116 for (CFListIterator j= result; j.hasItem(); j++, k++) 117 { 118 j.getItem() *= S; 119 CanonicalForm q; 120 j.getItem()= mod (j.getItem(), k.getItem()); 121 j.getItem()= reduce (j.getItem(), M); 122 } 123 result.append (T); 124 } 125 } 126 127 static inline 128 CFList mapinto (const CFList& L) 129 { 130 CFList result; 131 for (CFListIterator i= L; i.hasItem(); i++) 132 result.append (mapinto (i.getItem())); 133 return result; 134 } 135 136 static inline 137 int mod (const CFList& L, const CanonicalForm& p) 138 { 139 for (CFListIterator i= L; i.hasItem(); i++) 140 { 141 if (mod (i.getItem(), p) == 0) 142 return 0; 143 } 144 return 1; 145 } 146 147 148 static inline void 149 chineseRemainder (const CFList & x1, const CanonicalForm & q1, 150 const CFList & x2, const CanonicalForm & q2, 151 CFList & xnew, CanonicalForm & qnew) 152 { 153 ASSERT (x1.length() == x2.length(), "expected lists of equal length"); 154 CanonicalForm tmp1, tmp2; 155 CFListIterator j= x2; 156 for (CFListIterator i= x1; i.hasItem() && j.hasItem(); i++, j++) 157 { 158 chineseRemainder (i.getItem(), q1, j.getItem(), q2, tmp1, tmp2); 159 xnew.append (tmp1); 160 } 161 qnew= tmp2; 162 } 163 164 static inline 165 CFList Farey (const CFList& L, const CanonicalForm& q) 166 { 167 CFList result; 168 for (CFListIterator i= L; i.hasItem(); i++) 169 result.append (Farey (i.getItem(), q)); 170 return result; 171 } 172 173 static inline 174 CFList replacevar (const CFList& L, const Variable& a, const Variable& b) 175 { 176 CFList result; 177 for (CFListIterator i= L; i.hasItem(); i++) 178 result.append (replacevar (i.getItem(), a, b)); 179 return result; 180 } 181 182 CFList 183 modularDiophant (const CanonicalForm& f, const CFList& factors, 184 const CanonicalForm& M) 185 { 186 bool save_rat=!isOn (SW_RATIONAL); 187 On (SW_RATIONAL); 188 CanonicalForm F= f*bCommonDen (f); 189 CFList products= factors; 190 for (CFListIterator i= products; i.hasItem(); i++) 191 i.getItem() *= bCommonDen (i.getItem()); 192 if (products.getFirst().level() == 1) 193 products.insert (Lc (F)); 194 CanonicalForm bound= maxNorm (F); 195 CFList leadingCoeffs; 196 leadingCoeffs.append (lc (F)); 197 CanonicalForm dummy; 198 for (CFListIterator i= products; i.hasItem(); i++) 199 { 200 leadingCoeffs.append (lc (i.getItem())); 201 dummy= maxNorm (i.getItem()); 202 bound= (dummy > bound) ? dummy : bound; 203 } 204 bound *= maxNorm (Lc (F))*maxNorm (Lc(F))*bound; 205 bound *= bound*bound; 206 bound= power (bound, degree (M)); 207 bound *= power (CanonicalForm (2),degree (f)); 208 CanonicalForm bufBound= bound; 209 int i = cf_getNumBigPrimes() - 1; 210 int p; 211 CFList resultModP, result, newResult; 212 CanonicalForm q (0), newQ; 213 bool fail= false; 214 Variable a= M.mvar(); 215 Variable b= Variable (2); 216 setReduce (M.mvar(), false); 217 CanonicalForm mipo= bCommonDen (M)*M; 218 Off (SW_RATIONAL); 219 CanonicalForm modMipo; 220 leadingCoeffs.append (lc (mipo)); 221 CFList tmp1, tmp2; 222 bool equal= false; 223 int count= 0; 224 do 225 { 226 p = cf_getBigPrime( i ); 227 i--; 228 while ( i >= 0 && mod( leadingCoeffs, p ) == 0) 229 { 230 p = cf_getBigPrime( i ); 231 i--; 232 } 233 234 ASSERT (i >= 0, "ran out of primes"); //sic 235 236 setCharacteristic (p); 237 modMipo= mapinto (mipo); 238 modMipo /= lc (modMipo); 239 resultModP= CFList(); 240 tryDiophantine (resultModP, mapinto (F), mapinto (products), modMipo, fail); 241 setCharacteristic (0); 242 if (fail) 243 { 244 fail= false; 245 continue; 246 } 247 248 if ( q.isZero() ) 249 { 250 result= replacevar (mapinto(resultModP), a, b); 251 q= p; 252 } 253 else 254 { 255 result= replacevar (result, a, b); 256 newResult= CFList(); 257 chineseRemainder( result, q, replacevar (mapinto (resultModP), a, b), 258 p, newResult, newQ ); 259 q= newQ; 260 result= newResult; 261 if (newQ > bound) 262 { 263 count++; 264 tmp1= replacevar (Farey (result, q), b, a); 265 if (tmp2.isEmpty()) 266 tmp2= tmp1; 267 else 268 { 269 equal= true; 270 CFListIterator k= tmp1; 271 for (CFListIterator j= tmp2; j.hasItem(); j++, k++) 272 { 273 if (j.getItem() != k.getItem()) 274 equal= false; 275 } 276 if (!equal) 277 tmp2= tmp1; 278 } 279 if (count > 2) 280 { 281 bound *= bufBound; 282 equal= false; 283 count= 0; 284 } 285 } 286 if (newQ > bound && equal) 287 { 288 On( SW_RATIONAL ); 289 result= tmp2; 290 CFList bufResult= result; 291 setReduce (M.mvar(), true); 292 if (factors.getFirst().level() == 1) 293 { 294 result.removeFirst(); 295 CFListIterator j= factors; 296 CanonicalForm denf= bCommonDen (f); 297 for (CFListIterator i= result; i.hasItem(); i++, j++) 298 i.getItem() *= Lc (j.getItem())*denf; 299 } 300 if (factors.getFirst().level() != 1 && 301 !bCommonDen (factors.getFirst()).isOne()) 302 { 303 CanonicalForm denFirst= bCommonDen (factors.getFirst()); 304 for (CFListIterator i= result; i.hasItem(); i++) 305 i.getItem() *= denFirst; 306 } 307 308 CanonicalForm test= 0; 309 CFListIterator jj= factors; 310 for (CFListIterator ii= result; ii.hasItem(); ii++, jj++) 311 test += ii.getItem()*(f/jj.getItem()); 312 if (!test.isOne()) 313 { 314 bound *= bufBound; 315 equal= false; 316 count= 0; 317 setReduce (M.mvar(), false); 318 result= bufResult; 319 Off (SW_RATIONAL); 320 } 321 else 322 break; 323 } 324 } 325 } while (1); 326 if (save_rat) Off(SW_RATIONAL); 327 return result; 328 } 34 329 35 330 CanonicalForm … … 1452 1747 CFList diophantine (const CanonicalForm& F, const CFList& factors) 1453 1748 { 1749 if (getCharacteristic() == 0) 1750 { 1751 Variable v; 1752 bool hasAlgVar= hasFirstAlgVar (F, v); 1753 for (CFListIterator i= factors; i.hasItem() && !hasAlgVar; i++) 1754 hasAlgVar= hasFirstAlgVar (i.getItem(), v); 1755 if (hasAlgVar) 1756 { 1757 CFList result= modularDiophant (F, factors, getMipo (v)); 1758 return result; 1759 } 1760 } 1761 1454 1762 CanonicalForm buf1, buf2, buf3, S, T; 1455 1763 CFListIterator i= factors; … … 2454 2762 CFList bufFactors2= factors; 2455 2763 bufFactors2.removeFirst(); 2456 diophant.removeFirst();2457 CFListIterator iter= diophant;2458 2764 CanonicalForm s,t; 2459 2765 extgcd (bufFactors2.getFirst(), bufFactors2.getLast(), s, t);
Note: See TracChangeset
for help on using the changeset viewer.