Changeset 150e5d in git


Ignore:
Timestamp:
Jun 24, 2010, 3:10:14 PM (13 years ago)
Author:
Hans Schoenemann <hannes@…>
Branches:
(u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'f875bbaccd0831e36aaed09ff6adeb3eb45aeb94')
Children:
979dab6fd11ae8dfb1094472739d3ad502c5b9bd
Parents:
4bc0a3eac0a3be2c9f42b91830fd54c36de1cd34
Message:
misc.cc -> misc_ip.cc

git-svn-id: file:///usr/local/Singular/svn/trunk@12910 2c84dea3-7e68-4137-9b89-c4e89433aadc
Location:
Singular
Files:
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • Singular/Makefile.in

    r4bc0a3e r150e5d  
    178178    Minor.cc \
    179179    MinorProcessor.cc \
    180     MinorInterface.cc \
    181     misc.cc
     180    MinorInterface.cc
    182181
    183182# stuff for MP
  • Singular/misc_ip.cc

    r4bc0a3e r150e5d  
    1 /****************************************
    2 *  Computer Algebra System SINGULAR     *
    3 ****************************************/
    4 /*
    5 * ABSTRACT:
    6 */
     1/*****************************************************************************\
     2 * Computer Algebra System SINGULAR   
     3\*****************************************************************************/
     4/** @file misc.cc
     5 *
     6 * This file provides miscellaneous functionality.
     7 *
     8 * For more general information, see the documentation in
     9 * misc.h.
     10 *
     11 * @author Frank Seelisch
     12 *
     13 * @internal @version \$Id$
     14 *
     15 **/
     16/*****************************************************************************/
     17
     18// include header files
     19#include "mod2.h"
     20#include "lists.h"
     21#include "longrat.h" /* We only need bigints. */
     22#include "misc.h"
     23
     24/* This works by Newton iteration, i.e.,
     25      a(1)   = n;
     26      a(i+1) = a(i)/2 + n/2/a(i), i > 0.
     27   This sequence is guaranteed to decrease monotonously and
     28   it is known to converge fast.
     29   All used numbers are bigints. */
     30number approximateSqrt(const number n)
     31{
     32  if (nlIsZero(n)) { number zero = nlInit(0, NULL); return zero; }
     33  number temp1; number temp2;
     34  number one = nlInit(1, NULL);
     35  number two = nlInit(2, NULL);
     36  number m = nlCopy(n);
     37  number mOld = nlSub(m, one); /* initially required to be different from m */
     38  number nHalf = nlIntDiv(n, two);
     39  bool check = true;
     40  while (!nlEqual(m, mOld) && check)
     41  {
     42    temp1 = nlIntDiv(m, two);
     43    temp2 = nlIntDiv(nHalf, m);
     44    mOld = m;
     45    m = nlAdd(temp1, temp2);
     46    nlDelete(&temp1, NULL); nlDelete(&temp2, NULL);
     47    temp1 = nlMult(m, m);
     48    check = nlGreater(temp1, n);
     49    nlDelete(&temp1, NULL);
     50  }
     51  nlDelete(&mOld, NULL); nlDelete(&two, NULL); nlDelete(&nHalf, NULL);
     52  while (!check)
     53  {
     54    temp1 = nlAdd(m, one);
     55    nlDelete(&m, NULL);
     56    m = temp1;
     57    temp1 = nlMult(m, m);
     58    check = nlGreater(temp1, n);
     59    nlDelete(&temp1, NULL);
     60  }
     61  temp1 = nlSub(m, one);
     62  nlDelete(&m, NULL);
     63  nlDelete(&one, NULL);
     64  m = temp1;
     65  return m;
     66}
     67
     68/* returns the quotient resulting from division of n by the prime as many
     69   times as possible without remainder; afterwards, the parameter times
     70   will contain the highest exponent e of p such that p^e divides n
     71   e.g., divTimes(48, 4, t) = 3 with t = 2, since 48 = 4*4*3;
     72   n is expected to be a bigint; returned type is also bigint */
     73number divTimes(const number n, const int p, int* times)
     74{
     75  number nn = nlCopy(n);
     76  number dd = nlInit(p, NULL);
     77  number rr = nlIntMod(nn, dd);
     78  *times = 0;
     79  while (nlIsZero(rr))
     80  {
     81    (*times)++;
     82    number temp = nlIntDiv(nn, dd);
     83    nlDelete(&nn, NULL);
     84    nn = temp;
     85    nlDelete(&rr, NULL);
     86    rr = nlIntMod(nn, dd);
     87  }
     88  nlDelete(&rr, NULL); nlDelete(&dd, NULL);
     89  return nn;
     90}
     91
     92/* returns an object of type lists which contains the entries
     93   theInts[0..(length-1)] as INT_CMDs*/
     94lists makeListsObject(const int* theInts, int length)
     95{
     96  lists L=(lists)omAllocBin(slists_bin);
     97  L->Init(length);
     98  for (int i = 0; i < length; i++)
     99    { L->m[i].rtyp = INT_CMD; L->m[i].data = (void*)theInts[i]; }
     100  return L;
     101}
     102
     103/* returns the i-th bit of the binary number which arises by
     104   concatenating array[length-1], ..., array[1], array[0],
     105   where array[0] contains the 32 lowest bits etc.;
     106   i is assumed to be small enough to address a valid index
     107   in the given array */
     108bool getValue(const int i, const unsigned int* ii)
     109{
     110  int index = i / 32;
     111  int offset = i % 32;
     112  unsigned int v = 1 << offset;
     113  return ((ii[index] & v) != 0);
     114}
     115
     116/* sets the i-th bit of the binary number which arises by
     117   concatenating array[length-1], ..., array[1], array[0],
     118   where array[0] contains the 32 lowest bits etc.;
     119   i is assumed to be small enough to address a valid index
     120   in the given array */
     121void setValue(const int i, bool value, unsigned int* ii)
     122{
     123  int index = i / 32;
     124  int offset = i % 32;
     125  unsigned int v = 1 << offset;
     126  if (value && ((ii[index] & v) != 0)) return;
     127  if ((!value) && ((ii[index] & v) == 0)) return;
     128  if (value && ((ii[index] & v) == 0)) { ii[index] += v; return; }
     129  if ((!value) && ((ii[index] & v) != 0)) { ii[index] -= v; return; }
     130}
     131
     132/* returns whether i is less than or equal to the bigint number n */
     133bool isLeq(const int i, const number n)
     134{
     135  number iN = nlInit(i - 1, NULL);
     136  bool result = nlGreater(n, iN);
     137  nlDelete(&iN, NULL);
     138  return result;
     139}
     140
     141lists primeFactorisation(const number n, const int pBound)
     142{
     143  number nn = nlCopy(n); int i;
     144  int pCounter = 0; /* for counting the number of mutually distinct
     145                       prime factors in n */
     146  /* we assume that there are at most 1000 mutually distinct prime
     147     factors in n */
     148  int* primes = new int[1000]; int* multiplicities = new int[1000];
     149
     150  /* extra treatment for the primes 2 and 3;
     151     all other primes are equal to +1/-1 mod 6 */
     152  int e; number temp;
     153  temp = divTimes(nn, 2, &e); nlDelete(&nn, NULL); nn = temp;
     154  if (e > 0) { primes[pCounter] = 2; multiplicities[pCounter++] = e; }
     155  temp = divTimes(nn, 3, &e); nlDelete(&nn, NULL); nn = temp;
     156  if (e > 0) { primes[pCounter] = 3; multiplicities[pCounter++] = e; }
     157
     158  /* now we simultaneously:
     159     - build the sieve of Erathostenes up to s,
     160     - divide out each prime factor of nn that we find along the way
     161       (This may result in an earlier termination.) */
     162
     163  int s = 67108864;       /* = 2^26 */
     164  int maxP = 2147483647; /* = 2^31 - 1, by the way a Mersenne prime */
     165  if ((pBound != 0) && (pBound < maxP)) maxP = pBound;
     166  unsigned int* isPrime = new unsigned int[s];
     167  /* the lowest bit of isPrime[0] stores whether 0 is a prime,
     168     next bit is for 1, next for 2, etc. i.e.
     169     intended usage is: isPrime[0] = 10100000100010100010100010101100.
     170     This goes on up to isPrime[67108863]; the highest bit of this
     171     unsigned int corresponds to 67108863*32+31 = 2^31-1.
     172     We shall make use only of bits which correspond to numbers =
     173     -1 or +1 mod 6. */
     174  for (i = 0; i < s; i++) isPrime[i] = 4294967295; /* all 32 bits set */
     175  int p = 5; bool add2 = true;
     176  while ((p <= maxP) && (isLeq(p, nn)))
     177  {
     178    /* at this point, p is guaranteed to be a prime;
     179       we divide nn by the highest power of p and store p
     180       if nn is at all divisible by p */
     181    temp = divTimes(nn, p, &e);
     182    nlDelete(&nn, NULL); nn = temp;
     183    if (e > 0) { primes[pCounter] = p; multiplicities[pCounter++] = e; }
     184    /* invalidate all multiples of p, starting with 2*p */
     185    i = 2 * p;
     186    while (i <= s) { setValue(i, false, isPrime); i += p; }
     187    /* move on to the next prime in the sieve; we either add 2 or 4
     188       in order to visit just the numbers equal to -1/+1 mod 6 */
     189    if (add2) { p += 2; add2 = false; }
     190    else      { p += 4; add2 = true;  }
     191    while ((p <= maxP) && (isLeq(p, nn)) && (!getValue(p, isPrime)))
     192    {
     193      if (add2) { p += 2; add2 = false; }
     194      else      { p += 4; add2 = true;  }
     195    }
     196  }
     197
     198  /* build return structure and clean up */
     199  delete [] isPrime;
     200  lists primesL = makeListsObject(primes, pCounter);
     201  lists multiplicitiesL = makeListsObject(multiplicities, pCounter);
     202  delete [] primes; delete [] multiplicities;
     203  lists L=(lists)omAllocBin(slists_bin);
     204  L->Init(3);
     205  L->m[0].rtyp = BIGINT_CMD; L->m[0].data = (void *)nn;
     206  /* try to fit nn into an int: */
     207  int nnAsInt = nlInt(nn, NULL);
     208  if (nlIsZero(nn) || (nnAsInt != 0))
     209  { L->m[0].rtyp = INT_CMD; L->m[0].data = (void *)nnAsInt; }
     210  L->m[1].rtyp = LIST_CMD; L->m[1].data = (void *)primesL;
     211  L->m[2].rtyp = LIST_CMD; L->m[2].data = (void *)multiplicitiesL;
     212  return L;
     213}
    7214
    8215#include <string.h>
     
    13220#include <time.h>
    14221
    15 #include "mod2.h"
    16222#include <mylimits.h>
    17223#include "omalloc.h"
    18 #include "structs.h"
    19 #include "tok.h"
    20224#include "options.h"
    21225#include "febase.h"
Note: See TracChangeset for help on using the changeset viewer.