📄 quasic.sh01
字号:
---- Cut Here and unpack ----#!/bin/sh# shar: Shell Archiver (v1.22)## # ## Run the following text with /bin/sh to create:# quasi.h# quasi.c#if test -r s2_seq_.tmpthen echo "Must unpack archives in sequence!" next=`cat s2_seq_.tmp`; echo "Please unpack part $next next" exit 1; fiecho "x - extracting quasi.h (Text)"sed 's/^X//' << 'SHAR_EOF' > quasi.h &&X/* quasi.h Quasi-Random Number generator, an object orientedX implementation in C.XX returns an n-dimensional vector of values in 0.0..1.0X maximum n is currently hardwired to 52XX See W.H. Press and S.A. Teukolsky, 1989, Quasi- (that is,X Sub-) Random Numbers, Computers in Physics V3, No. 6,X (Nov/Dec 1989), pp. 76-79XXX rcsid: @(#)quasi.h 1.5 10:15:46 4/18/94 EFCXX*/XX#ifndef QUASI_RANDOM_H_X#define QUASI_RANDOM_H_ 1.5XXXtypedef struct /* data structure to maintain internal information */X{ /* this allows multiple independent generators to exist inX a single application (each one would have its ownX QRStruct) */XX int err_flag; /* err_flag == 0 if all is well */X int dim;X unsigned long int index;X unsigned long int *ix;X} QRStruct;XX#ifdef __cplusplusXextern "C" {X#endifXX/* initialized the data structure for this dimension */Xint QuasiRandomInitialize(QRStruct* qr, int dimension);XX/* release internal storage for this QRStruct */Xvoid QuasiRandomRelease(QRStruct* qr);XX/* get an n-dimensional quasi-random number */Xvoid QuasiRandomNumber(QRStruct* qr, float* x);XXX#ifdef __cplusplusX}X#endifXX#endifXXXXXSHAR_EOFchmod 0644 quasi.h || echo "restore of quasi.h fails"echo "x - extracting quasi.c (Text)"sed 's/^X//' << 'SHAR_EOF' > quasi.c &&X/* quasi.c Implementation of the Quasi-Random Number generatorX currently hardwired to no more than 52 dimensionsXX See W.H. Press and S.A. Teukolsky, 1989, Quasi- (that is,X Sub-) Random Numbers, Computers in Physics V3, No. 6,X (Nov/Dec 1989), pp. 76-79XXX*/XXstatic char rcsid[] = "@(#)quasi.c 1.5 10:15:59 4/18/94 EFC";XX#include <stdio.h>XX#include "quasi.h"XX/* the primitive polynomial coefficients for up to degree 8 */Xstatic int ip[] = { 0, 1, 1, 2, 1, 4, 2, 4, 7, 11, 13, 14,X 1, 13, 16, 19, 22, 25,X 1, 4, 7, 8, 14, 19, 21, 28, 31, 32, 37, 41, 42,X 50, 55, 56, 59, 62,X 14, 21, 22, 38, 47, 49, 50, 52, 56, 67, 70, 84,X 97, 103, 115, 122 };Xstatic int mdeg[] = { 1, 2, 3, 3, 4, 4, 5, 5, 5, 5, 5, 5,X 6, 6, 6, 6, 6, 6,X 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,X 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8X };XXstatic int maxdim = sizeof(mdeg) / sizeof(int);XXstatic int maxbit = 30; /* must be no more thanX number of bits in ulong - 1 */XXstatic unsigned long int* iv = NULL;Xstatic double factor = 1.0;Xstatic int instances = 0;XX#define INDEX(k,j) [(k) + (j-1) * maxdim]XXXstatic void QuasiInit() /* initialize the direction numbers */X{ /* only done once */X int j, k, l, ipp, niv;X unsigned long int mval, limit;X unsigned long int i;X X iv = (unsigned long int *)malloc( (niv = maxdim * maxbit)X * sizeof( unsigned long int) );XX for (k = 0; k < niv; k++)X iv[k] = 0;XX for (k = 0; k < maxdim; k++)X iv[k] = 1;XX mval = 4;X ipp = 1;XX limit = (1L << (maxbit-1) );XX for (k = maxdim, j = 0; k < niv-1; k += 2)X {X iv[k] = ipp;X if (++j == maxdim)X {X if ( mval < limit )X mval *= 2;X ipp += 2;X j = 0;X }XX if ( ipp > mval )X ipp = 1;X X iv[k+1] = ipp;X if (++j == maxdim)X {X if ( mval < limit )X mval *= 2;X ipp += 2;X j = 0;X }X elseX {X ipp += 2;X if ( ipp > mval )X ipp = 1;X }X XX }XX for (k = 0; k < maxdim; k++)X {X /* normalize the set iv values */X for (j = 1; j <= mdeg[k]; j++)X iv INDEX(k,j) *= (1L << (maxbit - j));XX /* calcululate the rest of the iv values */X for (j = mdeg[k] + 1; j <= maxbit; j++)X {X ipp = ip[k];X X /* calculate Gray code of iv */X i = iv INDEX(k, j - mdeg[k]);X i ^= i / (1L << mdeg[k]);X X for (l = mdeg[k] - 1; l >= 1; l--)X {X if ( ipp & 1 )X i ^= iv INDEX(k, j-l);X ipp /= 2;X }XX iv INDEX(k,j) = i;XX }X }XX factor = 1.0 / (1L << maxbit);XX X}XXint QuasiRandomInitialize(QRStruct* qr, int dimension)X{X int k;XX qr->dim = dimension;X qr->index = 0;XX if ( qr->dim > maxdim ) /* if dimension is too large */X { /* truncate and set error flag */X qr->dim = maxdim;X qr->err_flag = -1;X }X elseX qr->err_flag = 0;X X qr->ix = (unsigned long int *)malloc(qr->dim * sizeof( unsigned long int) );XX for (k = 0; k < qr->dim; k++)X qr->ix[k] = 0L;XX X if ( instances++ == 0 )X QuasiInit();XX return qr->err_flag;X}XXvoid QuasiRandomRelease(QRStruct* qr)X{X if ( --instances == 0 )X free( iv );XX free( qr->ix );XX qr->err_flag = -9;X}XXvoid QuasiRandomNumber(QRStruct* qr, float* x)X{X int i, j, k;X unsigned long int im = qr->index++;XX /* find rightmost zero bit */X for (j = 0; j < maxbit; j++, im >>= 1)X if ( (im & 1L) == 0 )X break;XX i = j * maxdim;XX for (k = 0; k < qr->dim; k++)X {X qr->ix[k] ^= iv[i + k]; /* integer values */X x[k] = (float) ( factor * (double)qr->ix[k] );X }XX}XXX#ifdef MAINXX/* Demonstration test code, writes quasirandom numbers to standard outXXX To compile with the test driver:XX cc -DMAIN -o quasi quasi.c -lmXXXX usage:XX quasi [points [dimension]]XXX*/XXint main(int argc, char** argv)X{X int i, k;X float *x;X QRStruct qr;X int dim = 0;X int points = 0;XX if ( argc > 1 )X points = atoi( argv[1] );XX if ( argc > 2 )X dim = atoi( argv[2] );XX if ( points < 1 )X points = 100; /* default to 100 points */XX if ( dim < 1 )X dim = 2; /* default to 2 dimensional points */XXX x = (float *)malloc( dim * sizeof( float ) );XX QuasiRandomInitialize( &qr, dim );XX for (i = 0; i < points; i++)X {X QuasiRandomNumber( &qr, x );X for (k = 0; k < dim; k++)X printf("%f ", x[k]);X putchar( '\n' );X }XXX QuasiRandomRelease( &qr );XX free( x );XX}XX#endifXXXSHAR_EOFchmod 0644 quasi.c || echo "restore of quasi.c fails"exit 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -