Changeset 150e5d in git
- Timestamp:
- Jun 24, 2010, 3:10:14 PM (13 years ago)
- Branches:
- (u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'f875bbaccd0831e36aaed09ff6adeb3eb45aeb94')
- Children:
- 979dab6fd11ae8dfb1094472739d3ad502c5b9bd
- Parents:
- 4bc0a3eac0a3be2c9f42b91830fd54c36de1cd34
- Location:
- Singular
- Files:
-
- 1 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/Makefile.in
r4bc0a3e r150e5d 178 178 Minor.cc \ 179 179 MinorProcessor.cc \ 180 MinorInterface.cc \ 181 misc.cc 180 MinorInterface.cc 182 181 183 182 # 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. */ 30 number 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 */ 73 number 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*/ 94 lists 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 */ 108 bool 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 */ 121 void 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 */ 133 bool 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 141 lists 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 } 7 214 8 215 #include <string.h> … … 13 220 #include <time.h> 14 221 15 #include "mod2.h"16 222 #include <mylimits.h> 17 223 #include "omalloc.h" 18 #include "structs.h"19 #include "tok.h"20 224 #include "options.h" 21 225 #include "febase.h"
Note: See TracChangeset
for help on using the changeset viewer.