Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346/****************************************************************************1**2*W infuncs.c GAP source Martin Schönert3** & Alice Niemeyer4** & Werner Nickel5**6**7*Y Copyright (C) 1996, Lehrstuhl D für Mathematik, RWTH Aachen, Germany8*Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland9*Y Copyright (C) 2002 The GAP Group10**11** This file contains integer related functions which are independent of the12** large integer representation in use. See integer.c and gmpints.c for13** other things14*/151617#include "system.h" /* Ints, UInts */181920#include "gasman.h" /* garbage collector */21#include "objects.h" /* objects */22#include "scanner.h" /* scanner */2324#include "gvars.h" /* global variables */2526#include "calls.h" /* generic call mechanism */27#include "opers.h" /* generic operations */2829#include "ariths.h" /* basic arithmetic */3031#include "bool.h" /* booleans */3233#include "intfuncs.h" /* integers */3435#include "integer.h"3637#include "gap.h" /* error handling, initialisation */3839#include "records.h" /* generic records */40#include "precord.h" /* plain records */4142#include "lists.h" /* generic lists */43#include "string.h" /* strings */4445#include "saveload.h" /* saving and loading */4647#include "code.h" /* coder */48#include "thread.h" /* threads */49#include "tls.h" /* thread-local storage */505152#include <stdio.h>535455/****************************************************************************56**57*F FuncSIZE_OBJ(<self>,<obj>)58**59** 'SIZE_OBJ( <obj> )' returns the size of a nonimmediate object. It can be60** used to debug memory use.61*/62Obj FuncSIZE_OBJ (63Obj self,64Obj a)65{66return INTOBJ_INT(SIZE_OBJ(a));67}686970/****************************************************************************71**72** * * * * * * * "Mersenne twister" random numbers * * * * * * * * * * * * *73**74** Part of this code for fast generation of 32 bit pseudo random numbers with75** a period of length 2^19937-1 and a 623-dimensional equidistribution is76** taken from:77** http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html78** (Also look in Wikipedia for "Mersenne twister".)79** We use the file mt19937ar.c, version 2002/1/26.80*/8182/****************************************************************************83**84*F InitRandomMT( <initstr> )85**86** Returns a string that can be used as data structure of a new MT random87** number generator. <initstr> can be an arbitrary string as seed.88*/89#define MATRIX_A 0x9908b0dfUL /* constant vector a */90#define UPPER_MASK 0x80000000UL /* most significant w-r bits */91#define LOWER_MASK 0x7fffffffUL /* least significant r bits */9293void initGRMT(UInt4 *mt, UInt4 s)94{95UInt4 mti;96mt[0]= s & 0xffffffffUL;97for (mti=1; mti<624; mti++) {98mt[mti] =99(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);100mt[mti] &= 0xffffffffUL;101}102/* store mti as last entry of mt[] */103mt[624] = mti;104}105106/* to read a seed string independently of endianness */107static inline UInt4 uint4frombytes(UChar *s)108{109UInt4 res;110res = s[3]; res <<= 8;111res += s[2]; res <<= 8;112res += s[1]; res <<= 8;113res += s[0];114return res;115}116117Obj FuncInitRandomMT( Obj self, Obj initstr)118{119Obj str;120UChar *init_key;121UInt4 *mt, key_length, i, j, k, N=624;122123/* check the seed, given as string */124while (! IsStringConv(initstr)) {125initstr = ErrorReturnObj(126"<initstr> must be a string, not a %s)",127(Int)TNAM_OBJ(initstr), 0L,128"you can replace <initstr> via 'return <initstr>;'" );129}130131/* store array of 624 UInt4 and one UInt4 as counter "mti" and an132endianness marker */133str = NEW_STRING(4*626);134SET_LEN_STRING(str, 4*626);135mt = (UInt4*) CHARS_STRING(str);136/* here the counter mti is set to 624 */137initGRMT(mt, 19650218UL);138i=1; j=0;139/* Do not set these up until all garbage collection is done */140init_key = CHARS_STRING(initstr);141key_length = GET_LEN_STRING(initstr) / 4;142k = (N>key_length ? N : key_length);143for (; k; k--) {144mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL))145+ uint4frombytes(init_key+4*j) + j;146mt[i] &= 0xffffffffUL;147i++; j++;148if (i>=N) { mt[0] = mt[N-1]; i=1; }149if (j>=key_length) j=0;150}151for (k=N-1; k; k--) {152mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - i;153mt[i] &= 0xffffffffUL;154i++;155if (i>=N) { mt[0] = mt[N-1]; i=1; }156}157mt[0] = 0x80000000UL;158/* gives string "1234" in little endian as marker */159mt[625] = 875770417UL;160return str;161}162163164/* internal, generates a random number on [0,0xffffffff]-interval165** argument <mt> is pointer to a string generated by InitRandomMT166** (the first 4*624 bytes are the random numbers, the last 4 bytes contain167** a counter)168*/169UInt4 nextrandMT_int32(UInt4* mt)170{171UInt4 mti, y, N=624, M=397;172static UInt4 mag01[2]={0x0UL, MATRIX_A};173174mti = mt[624];175if (mti >= N) {176int kk;177178for (kk=0;kk<N-M;kk++) {179y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);180mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];181}182for (;kk<N-1;kk++) {183y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);184mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL];185}186y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);187mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL];188189mti = 0;190}191192y = mt[mti++];193mt[624] = mti;194195/* Tempering */196y ^= (y >> 11);197y ^= (y << 7) & 0x9d2c5680UL;198y ^= (y << 15) & 0xefc60000UL;199y ^= (y >> 18);200201return y;202}203204/****************************************************************************205**206*F FuncHASHKEY_BAG(<self>,<obj>,<seed>,<offset>,<maxlen>)207**208** 'FuncHASHKEY_BAG' implements the internal function 'HASHKEY_BAG'.209**210** 'HASHKEY_BAG( <obj>, <seed>, <offset>, <maxlen> )'211**212** takes an non-immediate object and a small integer <int> and computes a213** hash value for the contents of the bag from these. (For this to be214** usable in algorithms, we need that objects of this kind are stored uniquely215** internally.216** The offset and the maximum number of bytes to process both count in217** bytes. The values passed to these parameters might depend on the word218** length of the computer.219** A <maxlen> value of -1 indicates infinity.220*/221222223//-----------------------------------------------------------------------------224// MurmurHash3 was written by Austin Appleby, and is placed in the public225// domain. The author hereby disclaims copyright to this source code.226227// Note - The x86 and x64 versions do _not_ produce the same results, as the228// algorithms are optimized for their respective platforms. You can still229// compile and run any of them on any platform, but your performance with the230// non-native version will be less than optimal.231232//-----------------------------------------------------------------------------233// MurmurHash3 was written by Austin Appleby, and is placed in the public234// domain. The author hereby disclaims copyright to this source code.235236/* Minor modifications to get it to compile in C rather than C++ and237integrate with GAP SL*/238239240#if HAVE_STDINT_H241#include <stdint.h>242#endif243244245//-----------------------------------------------------------------------------246// Platform-specific functions and macros247248249#define FORCE_INLINE static inline250251static inline uint32_t rotl32 ( uint32_t x, int8_t r )252{253return (x << r) | (x >> (32 - r));254}255#define ROTL32(x,y) rotl32(x,y)256257258static inline uint64_t rotl64 ( uint64_t x, int8_t r )259{260return (x << r) | (x >> (64 - r));261}262263#define ROTL64(x,y) rotl64(x,y)264265266267#define BIG_CONSTANT(x) (x##LLU)268269270//-----------------------------------------------------------------------------271// Block read - if your platform needs to do endian-swapping or can only272// handle aligned reads, do the conversion here273274FORCE_INLINE uint32_t getblock4 ( const uint32_t * p, int i )275{276return p[i];277}278279FORCE_INLINE uint64_t getblock8 ( const uint64_t * p, int i )280{281return p[i];282}283284//-----------------------------------------------------------------------------285// Finalization mix - force all bits of a hash block to avalanche286287FORCE_INLINE uint32_t fmix4 ( uint32_t h )288{289h ^= h >> 16;290h *= 0x85ebca6b;291h ^= h >> 13;292h *= 0xc2b2ae35;293h ^= h >> 16;294295return h;296}297298//----------299300FORCE_INLINE uint64_t fmix8 ( uint64_t k )301{302k ^= k >> 33;303k *= BIG_CONSTANT(0xff51afd7ed558ccd);304k ^= k >> 33;305k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);306k ^= k >> 33;307308return k;309}310311//-----------------------------------------------------------------------------312313void MurmurHash3_x86_32 ( const void * key, int len,314UInt4 seed, void * out )315{316const uint8_t * data = (const uint8_t*)key;317const int nblocks = len / 4;318319uint32_t h1 = seed;320321uint32_t c1 = 0xcc9e2d51;322uint32_t c2 = 0x1b873593;323324//----------325// body326327const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);328329int i;330for(i = -nblocks; i; i++)331{332uint32_t k1 = getblock4(blocks,i);333334k1 *= c1;335k1 = ROTL32(k1,15);336k1 *= c2;337338h1 ^= k1;339h1 = ROTL32(h1,13);340h1 = h1*5+0xe6546b64;341}342343//----------344// tail345346const uint8_t * tail = (const uint8_t*)(data + nblocks*4);347348uint32_t k1 = 0;349350switch(len & 3)351{352case 3: k1 ^= tail[2] << 16;353case 2: k1 ^= tail[1] << 8;354case 1: k1 ^= tail[0];355k1 *= c1; k1 = ROTL32(k1,16); k1 *= c2; h1 ^= k1;356};357358//----------359// finalization360361h1 ^= len;362363h1 = fmix4(h1);364365*(uint32_t*)out = h1;366}367368//-----------------------------------------------------------------------------369370void MurmurHash3_x86_128 ( const void * key, const int len,371uint32_t seed, void * out )372{373const uint8_t * data = (const uint8_t*)key;374const int nblocks = len / 16;375376uint32_t h1 = seed;377uint32_t h2 = seed;378uint32_t h3 = seed;379uint32_t h4 = seed;380381uint32_t c1 = 0x239b961b;382uint32_t c2 = 0xab0e9789;383uint32_t c3 = 0x38b34ae5;384uint32_t c4 = 0xa1e38b93;385386//----------387// body388389const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);390391int i;392for(i = -nblocks; i; i++)393{394uint32_t k1 = getblock4(blocks,i*4+0);395uint32_t k2 = getblock4(blocks,i*4+1);396uint32_t k3 = getblock4(blocks,i*4+2);397uint32_t k4 = getblock4(blocks,i*4+3);398399k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;400401h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;402403k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;404405h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;406407k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;408409h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;410411k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;412413h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;414}415416//----------417// tail418419const uint8_t * tail = (const uint8_t*)(data + nblocks*16);420421uint32_t k1 = 0;422uint32_t k2 = 0;423uint32_t k3 = 0;424uint32_t k4 = 0;425426switch(len & 15)427{428case 15: k4 ^= tail[14] << 16;429case 14: k4 ^= tail[13] << 8;430case 13: k4 ^= tail[12] << 0;431k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;432433case 12: k3 ^= tail[11] << 24;434case 11: k3 ^= tail[10] << 16;435case 10: k3 ^= tail[ 9] << 8;436case 9: k3 ^= tail[ 8] << 0;437k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;438439case 8: k2 ^= tail[ 7] << 24;440case 7: k2 ^= tail[ 6] << 16;441case 6: k2 ^= tail[ 5] << 8;442case 5: k2 ^= tail[ 4] << 0;443k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;444445case 4: k1 ^= tail[ 3] << 24;446case 3: k1 ^= tail[ 2] << 16;447case 2: k1 ^= tail[ 1] << 8;448case 1: k1 ^= tail[ 0] << 0;449k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;450};451452//----------453// finalization454455h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;456457h1 += h2; h1 += h3; h1 += h4;458h2 += h1; h3 += h1; h4 += h1;459460h1 = fmix4(h1);461h2 = fmix4(h2);462h3 = fmix4(h3);463h4 = fmix4(h4);464465h1 += h2; h1 += h3; h1 += h4;466h2 += h1; h3 += h1; h4 += h1;467468((uint32_t*)out)[0] = h1;469((uint32_t*)out)[1] = h2;470((uint32_t*)out)[2] = h3;471((uint32_t*)out)[3] = h4;472}473474//-----------------------------------------------------------------------------475476void MurmurHash3_x64_128 ( const void * key, const int len,477const UInt4 seed, void * out )478{479const uint8_t * data = (const uint8_t*)key;480const int nblocks = len / 16;481482uint64_t h1 = seed;483uint64_t h2 = seed;484485uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);486uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);487488//----------489// body490491const uint64_t * blocks = (const uint64_t *)(data);492493int i;494for(i = 0; i < nblocks; i++)495{496uint64_t k1 = getblock8(blocks,i*2+0);497uint64_t k2 = getblock8(blocks,i*2+1);498499k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;500501h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;502503k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;504505h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;506}507508//----------509// tail510511const uint8_t * tail = (const uint8_t*)(data + nblocks*16);512513uint64_t k1 = 0;514uint64_t k2 = 0;515516switch(len & 15)517{518case 15: k2 ^= (uint64_t)(tail[14]) << 48;519case 14: k2 ^= (uint64_t)(tail[13]) << 40;520case 13: k2 ^= (uint64_t)(tail[12]) << 32;521case 12: k2 ^= (uint64_t)(tail[11]) << 24;522case 11: k2 ^= (uint64_t)(tail[10]) << 16;523case 10: k2 ^= (uint64_t)(tail[ 9]) << 8;524case 9: k2 ^= (uint64_t)(tail[ 8]) << 0;525k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;526527case 8: k1 ^= (uint64_t)(tail[ 7]) << 56;528case 7: k1 ^= (uint64_t)(tail[ 6]) << 48;529case 6: k1 ^= (uint64_t)(tail[ 5]) << 40;530case 5: k1 ^= (uint64_t)(tail[ 4]) << 32;531case 4: k1 ^= (uint64_t)(tail[ 3]) << 24;532case 3: k1 ^= (uint64_t)(tail[ 2]) << 16;533case 2: k1 ^= (uint64_t)(tail[ 1]) << 8;534case 1: k1 ^= (uint64_t)(tail[ 0]) << 0;535k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;536};537538//----------539// finalization540541h1 ^= len; h2 ^= len;542543h1 += h2;544h2 += h1;545546h1 = fmix8(h1);547h2 = fmix8(h2);548549h1 += h2;550h2 += h1;551552((uint64_t*)out)[0] = h1;553((uint64_t*)out)[1] = h2;554}555556557Obj FuncHASHKEY_BAG(Obj self, Obj obj, Obj opSeed, Obj opOffset, Obj opMaxLen)558{559Int n;560Int offs;561562/* check the arguments */563while ( TNUM_OBJ(opSeed) != T_INT ) {564opSeed = ErrorReturnObj(565"HASHKEY_BAG: <seed> must be a small integer (not a %s)",566(Int)TNAM_OBJ(opSeed), 0L,567"you can replace <seed> via 'return <seed>;'" );568}569570do {571offs = -1;572573while ( TNUM_OBJ(opOffset) != T_INT ) {574opOffset = ErrorReturnObj(575"HASHKEY_BAG: <offset> must be a small integer (not a %s)",576(Int)TNAM_OBJ(opOffset), 0L,577"you can replace <offset> via 'return <offset>;'" );578}579offs = INT_INTOBJ(opOffset);580if ( offs < 0 || offs > SIZE_OBJ(obj)) {581opOffset = ErrorReturnObj(582"HashKeyBag: <offset> must be non-negative and less than the bag size",5830L, 0L,584"you can replace <offset> via 'return <offset>;'" );585offs = -1;586}587} while (offs < 0);588589while ( TNUM_OBJ(opMaxLen) != T_INT ) {590opMaxLen = ErrorReturnObj(591"HASHKEY_BAG: <maxlen> must be a small integer (not a %s)",592(Int)TNAM_OBJ(opMaxLen), 0L,593"you can replace <maxlen> via 'return <maxlen>;'" );594}595596n=SIZE_OBJ(obj)-offs;597598/* maximal number of bytes to read */599Int maxlen=INT_INTOBJ(opMaxLen);600if ((n>maxlen)&&(maxlen!=-1)) {n=maxlen;};601602return INTOBJ_INT(HASHKEY_BAG_NC( obj, (UInt4)INT_INTOBJ(opSeed), offs, (int) n));603}604605Int HASHKEY_BAG_NC (Obj obj, UInt4 seed, Int skip, int maxread){606#ifdef SYS_IS_64_BIT607UInt8 hashout[2];608MurmurHash3_x64_128 ( (const void *)((UChar *)ADDR_OBJ(obj)+skip),609maxread, seed, (void *) hashout);610return hashout[0] % (1UL << 60);611#else612UInt4 hashout;613MurmurHash3_x86_32 ( (const void *)((UChar *)ADDR_OBJ(obj)+skip),614maxread, seed, (void *) &hashout);615return hashout % (1UL << 28);616#endif617}618619Obj FuncJenkinsHash(Obj self, Obj op, Obj size)620{621return FuncHASHKEY_BAG(self, op, INTOBJ_INT(0L), INTOBJ_INT(0L), size);622}623624625/****************************************************************************626**627*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *628*/629630631/****************************************************************************632**633*V GVarFuncs . . . . . . . . . . . . . . . . . . list of functions to export634*/635static StructGVarFunc GVarFuncs [] = {636637638{ "HASHKEY_BAG", 4, "obj, int,int,int",639FuncHASHKEY_BAG, "src/integer.c:HASHKEY_BAG" },640641{ "JENKINS_HASH", 2, "obj, len",642FuncJenkinsHash, "src/integer.c:JENKINS_HASH" },643644{ "SIZE_OBJ", 1, "obj",645FuncSIZE_OBJ, "src/integer.c:SIZE_OBJ" },646647{ "InitRandomMT", 1, "initstr",648FuncInitRandomMT, "src/integer.c:InitRandomMT" },649650{ 0 }651652};653654655/****************************************************************************656**657*F InitKernel( <module> ) . . . . . . . . initialise kernel data structures658*/659static Int InitKernel (660StructInitInfo * module )661{662663664/* init filters and functions */665InitHdlrFuncsFromTable( GVarFuncs );666667return 0;668}669670671/****************************************************************************672**673*F InitLibrary( <module> ) . . . . . . . initialise library data structures674*/675static Int InitLibrary (676StructInitInfo * module )677{678/* init filters and functions */679InitGVarFuncsFromTable( GVarFuncs );680681/* return success */682return 0;683}684685686/****************************************************************************687**688*F InitInfoIntFuncs() . . . . . . . . . . . . . . . . . . table of init functions689*/690static StructInitInfo module = {691MODULE_BUILTIN, /* type */692"intfuncs", /* name */6930, /* revision entry of c file */6940, /* revision entry of h file */6950, /* version */6960, /* crc */697InitKernel, /* initKernel */698InitLibrary, /* initLibrary */6990, /* checkInit */7000, /* preSave */7010, /* postSave */7020 /* postRestore */703};704705StructInitInfo * InitInfoIntFuncs ( void )706{707return &module;708}709710711/****************************************************************************712**713*E intfuncs.c . . . . . . . . . . . . . . . . . . . . . . . . . . . ends here714*/715716717