Changeset cdf5c3c in git
- Timestamp:
- Jul 1, 2010, 5:55:18 PM (13 years ago)
- Branches:
- (u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'f875bbaccd0831e36aaed09ff6adeb3eb45aeb94')
- Children:
- a3c063797adc8c17337e64fe6c3a3902f1e6e20d
- Parents:
- 543deab35d35b991918d51d50605b76536e1c1da
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/misc_ip.cc
r543dea rcdf5c3c 142 142 } 143 143 144 #if 0 144 145 lists primeFactorisation(const number n, const int pBound) 145 146 { … … 178 179 We shall make use only of bits which correspond to numbers = 179 180 -1 or +1 mod 6. */ 180 for (i = 0; i < s; i++) isPrime[i] = ~0;/*4294967295*/; /* all 32 bits set */ 181 //for (i = 0; i < s; i++) isPrime[i] = ~0;/*4294967295*/; /* all 32 bits set */ 182 memset(isPrime,0xff,s*sizeof(unsigned int)); 181 183 int p=9; while((p<maxP) && (p>0)) { setValue(p,false,isPrime); p+=6; } 182 184 p = 5; bool add2 = true; … … 222 224 return L; 223 225 } 226 #else 227 /* Factoring , from gmp-demos 228 229 Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software 230 Foundation, Inc. 231 232 This program is free software; you can redistribute it and/or modify it under 233 the terms of the GNU General Public License as published by the Free Software 234 Foundation; either version 3 of the License, or (at your option) any later 235 version. 236 237 This program is distributed in the hope that it will be useful, but WITHOUT ANY 238 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 239 PARTICULAR PURPOSE. See the GNU General Public License for more details. 240 241 You should have received a copy of the GNU General Public License along with 242 this program. If not, see http://www.gnu.org/licenses/. */ 243 244 245 #include <stdlib.h> 246 #include <stdio.h> 247 #include <string.h> 248 249 #include <si_gmp.h> 250 251 static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6}; 252 253 void factor_using_division (mpz_t t, unsigned int limit, int *L, int &L_ind, int *ex) 254 { 255 mpz_t q, r; 256 unsigned long int f; 257 int ai; 258 unsigned *addv = add; 259 unsigned int failures; 260 261 mpz_init (q); 262 mpz_init (r); 263 264 f = mpz_scan1 (t, 0); 265 mpz_div_2exp (t, t, f); 266 while (f) 267 { 268 if ((L_ind>0) && (L[L_ind-1]==2)) ex[L_ind-1]++; 269 else 270 { 271 L[L_ind]=2; 272 L_ind++; 273 } 274 --f; 275 } 276 277 for (;;) 278 { 279 mpz_tdiv_qr_ui (q, r, t, 3); 280 if (mpz_cmp_ui (r, 0) != 0) break; 281 mpz_set (t, q); 282 if ((L_ind>0) && (L[L_ind-1]==3)) ex[L_ind-1]++; 283 else 284 { 285 L[L_ind]=3; 286 L_ind++; 287 } 288 } 289 290 for (;;) 291 { 292 mpz_tdiv_qr_ui (q, r, t, 5); 293 if (mpz_cmp_ui (r, 0) != 0) break; 294 mpz_set (t, q); 295 if ((L_ind>0) && (L[L_ind-1]==5)) ex[L_ind-1]++; 296 else 297 { 298 L[L_ind]=5; 299 L_ind++; 300 } 301 } 302 303 failures = 0; 304 f = 7; 305 ai = 0; 306 while (mpz_cmp_ui (t, 1) != 0) 307 { 308 mpz_tdiv_qr_ui (q, r, t, f); 309 if (mpz_cmp_ui (r, 0) != 0) 310 { 311 f += addv[ai]; 312 if (mpz_cmp_ui (q, f) < 0) break; 313 ai = (ai + 1) & 7; 314 failures++; 315 if (failures > limit) break; 316 } 317 else 318 { 319 mpz_swap (t, q); 320 if ((L_ind>0) && (L[L_ind-1]==f)) ex[L_ind-1]++; 321 else 322 { 323 L[L_ind]=f; 324 L_ind++; 325 } 326 failures = 0; 327 } 328 } 329 330 mpz_clear (q); 331 mpz_clear (r); 332 } 333 334 void factor_using_pollard_rho (mpz_t n, int a_int, int *L, int &L_ind, int *ex) 335 { 336 mpz_t x, x1, y, P; 337 mpz_t a; 338 mpz_t g; 339 mpz_t t1, t2; 340 int k, l, c, i; 341 342 mpz_init (g); 343 mpz_init (t1); 344 mpz_init (t2); 345 346 mpz_init_set_si (a, a_int); 347 mpz_init_set_si (y, 2); 348 mpz_init_set_si (x, 2); 349 mpz_init_set_si (x1, 2); 350 k = 1; 351 l = 1; 352 mpz_init_set_ui (P, 1); 353 c = 0; 354 355 while (mpz_cmp_ui (n, 1) != 0) 356 { 357 S2: 358 mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n); 359 mpz_sub (t1, x1, x); mpz_mul (t2, P, t1); mpz_mod (P, t2, n); 360 c++; 361 if (c == 20) 362 { 363 c = 0; 364 mpz_gcd (g, P, n); 365 if (mpz_cmp_ui (g, 1) != 0) goto S4; 366 mpz_set (y, x); 367 } 368 S3: 369 k--; 370 if (k > 0) goto S2; 371 372 mpz_gcd (g, P, n); 373 if (mpz_cmp_ui (g, 1) != 0) goto S4; 374 375 mpz_set (x1, x); 376 k = l; 377 l = 2 * l; 378 for (i = 0; i < k; i++) 379 { 380 mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n); 381 } 382 mpz_set (y, x); 383 c = 0; 384 goto S2; 385 S4: 386 do 387 { 388 mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n); 389 mpz_sub (t1, x1, y); mpz_gcd (g, t1, n); 390 } 391 while (mpz_cmp_ui (g, 1) == 0); 392 393 mpz_div (n, n, g); /* divide by g, before g is overwritten */ 394 395 if (!mpz_probab_prime_p (g, 3)) 396 { 397 do 398 { 399 mp_limb_t a_limb; 400 mpn_random (&a_limb, (mp_size_t) 1); 401 a_int = (int) a_limb; 402 } 403 while (a_int == -2 || a_int == 0); 404 405 factor_using_pollard_rho (g, a_int,L,L_ind,ex); 406 } 407 else 408 { 409 if ((L_ind>0) && (mpz_cmp_si(g,L[L_ind-1])==0)) ex[L_ind-1]++; 410 else 411 { 412 L[L_ind]=mpz_get_si(g); 413 L_ind++; 414 } 415 } 416 mpz_mod (x, x, n); 417 mpz_mod (x1, x1, n); 418 mpz_mod (y, y, n); 419 if (mpz_probab_prime_p (n, 3)) 420 { 421 if ((L_ind>0) && (mpz_cmp_si(n,L[L_ind-1])==0)) ex[L_ind-1]++; 422 else 423 { 424 L[L_ind]=mpz_get_si(n); 425 L_ind++; 426 } 427 break; 428 } 429 } 430 431 mpz_clear (g); 432 mpz_clear (P); 433 mpz_clear (t2); 434 mpz_clear (t1); 435 mpz_clear (a); 436 mpz_clear (x1); 437 mpz_clear (x); 438 mpz_clear (y); 439 } 440 441 void mpz_factor (mpz_t t, int *L, int & L_ind, int *ex) 442 { 443 unsigned int division_limit; 444 445 if (mpz_sgn (t) == 0) 446 return; 447 448 /* Set the trial division limit according the size of t. */ 449 division_limit = mpz_sizeinbase (t, 2); 450 if (division_limit > 1000) 451 division_limit = 1000 * 1000; 452 else 453 division_limit = division_limit * division_limit; 454 455 factor_using_division (t, division_limit, L, L_ind, ex); 456 457 if (mpz_cmp_ui (t, 1) != 0) 458 { 459 if (mpz_probab_prime_p (t, 3)) 460 { 461 if ((L_ind>0) && (mpz_cmp_si(t,L[L_ind-1])==0)) ex[L_ind-1]++; 462 else 463 { 464 L[L_ind]=mpz_get_si(t); 465 L_ind++; 466 } 467 } 468 else 469 factor_using_pollard_rho (t, 1, L,L_ind,ex); 470 } 471 } 472 473 lists primeFactorisation(const number n, const int pBound) 474 { 475 mpz_t t; 476 number nn = nlCopy(n); 477 lists L=(lists)omAllocBin(slists_bin); 478 L->Init(3); 479 L->m[0].rtyp = BIGINT_CMD; L->m[0].data = (void *)nn; 480 /* try to fit nn into an int: */ 481 int nnAsInt = nlInt(nn, NULL); 482 if (nlIsZero(nn) || (nnAsInt != 0)) 483 { 484 nlDelete(&nn,NULL); 485 L->m[0].rtyp = INT_CMD; 486 L->m[0].data = (void *)nnAsInt; 487 mpz_init_set_si(t,nnAsInt); 488 } 489 else 490 { 491 mpz_init_set(t,(mpz_ptr)nn); 492 } 493 int *LL=(int*)omAlloc0(1000*sizeof(int)); 494 int *ex=(int*)omAlloc0(1000*sizeof(int)); 495 int L_ind=0; 496 mpz_factor (t,LL,L_ind,ex); 497 498 int i; 499 for(i=0;i<L_ind;i++) ex[i]++; 500 L->m[1].rtyp = LIST_CMD; L->m[1].data = (void *)makeListsObject(LL,L_ind); 501 L->m[2].rtyp = LIST_CMD; L->m[2].data = (void *)makeListsObject(ex,L_ind); 502 return L; 503 } 504 #endif 224 505 225 506 #include <string.h>
Note: See TracChangeset
for help on using the changeset viewer.