Changeset cdf5c3c in git


Ignore:
Timestamp:
Jul 1, 2010, 5:55:18 PM (14 years ago)
Author:
Hans Schoenemann <hannes@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
a3c063797adc8c17337e64fe6c3a3902f1e6e20d
Parents:
543deab35d35b991918d51d50605b76536e1c1da
Message:
other method for primeFactorization

git-svn-id: file:///usr/local/Singular/svn/trunk@12941 2c84dea3-7e68-4137-9b89-c4e89433aadc
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/misc_ip.cc

    r543dea rcdf5c3c  
    142142}
    143143
     144#if 0
    144145lists primeFactorisation(const number n, const int pBound)
    145146{
     
    178179     We shall make use only of bits which correspond to numbers =
    179180     -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));
    181183  int p=9; while((p<maxP) && (p>0)) { setValue(p,false,isPrime); p+=6; }
    182184  p = 5; bool add2 = true;
     
    222224  return L;
    223225}
     226#else
     227/* Factoring , from gmp-demos
     228
     229Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software
     230Foundation, Inc.
     231
     232This program is free software; you can redistribute it and/or modify it under
     233the terms of the GNU General Public License as published by the Free Software
     234Foundation; either version 3 of the License, or (at your option) any later
     235version.
     236
     237This program is distributed in the hope that it will be useful, but WITHOUT ANY
     238WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
     239PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     240
     241You should have received a copy of the GNU General Public License along with
     242this 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
     251static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6};
     252
     253void 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
     334void 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  {
     357S2:
     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    }
     368S3:
     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;
     385S4:
     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
     441void 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
     473lists 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
    224505
    225506#include <string.h>
Note: See TracChangeset for help on using the changeset viewer.