18static double *lastPointValue = NULL;
20static long sequencesInUse = 0;
24#define N_SEQ_PREDEFINED 12
25static long Rvalues[N_SEQ_PREDEFINED] = {2, 3, 5, 7, 11, 19, 23, 29, 37, 47, 59, 67};
40 if ((sequencesInUse == 0 &&
41 (!(lastPointValue = malloc(
sizeof(*lastPointValue))) ||
42 !(R = malloc(
sizeof(*R))))) ||
43 (!(lastPointValue = realloc(lastPointValue, (sequencesInUse + 1) *
sizeof(*lastPointValue))) ||
44 !(R = realloc(R, (sequencesInUse + 1) *
sizeof(*R)))))
49 R[sequencesInUse] = *radix;
54 if ((ID = sequencesInUse) < N_SEQ_PREDEFINED)
62 for (i = 0; i < sequencesInUse; i++) {
73 lastPointValue[ID] = value;
91 if (ID > sequencesInUse || ID < 0)
94 lastPointValue[ID] = value;
112 if (ID > sequencesInUse || ID < 0)
115 f = 1 - lastPointValue[ID];
119 value = lastPointValue[ID] + (R[ID] + 1) * r - 1;
120 lastPointValue[ID] = value;
132static int32_t sDim = 12, nextPoint[12];
134static int32_t prime[] = {
231static double iprime[] = {
329static int32_t modSequenceInUse = 0;
330static int32_t primroots[][10] = {
331 {1, 2, 3, 3, 8, 11, 12, 14, 7, 18},
332 {12, 13, 17, 18, 29, 14, 18, 43, 41, 44},
333 {40, 30, 47, 65, 71, 28, 40, 60, 79, 89},
334 {56, 50, 52, 61, 108, 56, 66, 63, 60, 66},
335 {104, 76, 111, 142, 71, 154, 118, 84, 127, 142},
336 {84, 105, 186, 178, 188, 152, 165, 159, 103, 205},
337 {166, 173, 188, 181, 91, 233, 210, 217, 153, 212},
340static int32_t warnockOpt[] = {
442static double *quasi = NULL;
444int32_t power(int32_t a, int32_t b, int32_t m) {
446 for (i = 0; i < b; i++)
452 int32_t i, j, a[MAX_D + 1];
453 for (a[1] = 0, i = 2; i <= MAX_D; i++)
455 for (i = 2; i <= MAX_D / 2; i++)
456 for (j = 2; j <= MAX_D / i; j++)
458 for (i = 1, j = 0; i <= MAX_D; i++) {
461 iprime[j] = (double)i;
468int inhalt(
int dimen,
int atmost,
double tiny,
double *quasi) {
474 if (sDim < 1 || sDim > 1000)
479 eError = 0.9 * (1.0 / (atmost * prime[sDim - 1]) - 10.0 * tiny);
480 delta = 100 * tiny * (double)(atmost + 1) * log10((
double)atmost);
481 if (delta >= 0.09 * (eError - 10.0 * tiny))
487 for (i = 0; i < sDim; i++) {
488 iprime[i] = 1.0 / prime[i];
489 quasi[i] = iprime[i];
509 int32_t modID, dimen = 12, total_points = 100000;
512 if (!modSequenceInUse) {
517 quasi = malloc(
sizeof(*quasi) * sDim);
518 if (inhalt(dimen, total_points, tiny, quasi) < 0) {
519 fprintf(stderr,
"Unable to start modHalton sequence.\n");
523 modID = modSequenceInUse;
524 *radix = prime[modID];
539 int32_t dimen = 12, total_points = 100000;
542 if (inhalt(dimen, total_points, tiny, quasi) < 0) {
543 fprintf(stderr,
"Unable to start modHalton sequence.\n");
550int32_t generateModHaltSequence(
double *quasi,
double *dq,
double *wq,
long ID) {
551 int32_t i = (int32_t)ID, j, k, ytemp[40], xtemp[40], ltemp, mtemp;
560 while ((f - h) < eError)
566 quasi[i] = g + h - f;
569 mtemp = nextPoint[i];
573 ytemp[k] = mtemp % ltemp;
574 mtemp = mtemp / ltemp;
578 for (j = 0; j < k; j++) {
580 xtemp[j] = (warnockOpt[i] * power(primroots[i / 10][i % 10], ytemp[j], ltemp)) % ltemp;
581 xtemp[j] -= ytemp[j];
585 for (j = 0; j < k; j++) {
586 dq[i] += xtemp[j] * t;
591 for (j = 0; j < k; j++) {
595 xtemp[j] = (ytemp[j] * power(warnockOpt[i], i + 1, ltemp)) % ltemp;
600 xtemp[j] -= ytemp[j];
605 for (j = 0; j < k; j++) {
606 wq[i] += xtemp[j] * t;
625 static double *dq = NULL, *wq = NULL;
629 dq = malloc(
sizeof(*dq) * sDim);
631 wq = malloc(
sizeof(*wq) * sDim);
632 if (!modSequenceInUse) {
633 fprintf(stderr,
"ModHalton sequence not started.\n");
636 if (ID < 0 || ID > sDim - 1) {
637 fprintf(stderr,
"Invalid ID (%ld) provided\n", ID);
640 generateModHaltSequence(quasi, dq, wq, ID);
int64_t is_prime(int64_t number)
Determine if a number is prime.
int32_t startModHaltonSequence(int32_t *radix, double tiny)
Start a modified Halton sequence.
double nextModHaltonSequencePoint(long ID)
Retrieve the next point from the modified Halton sequence.
int32_t restartHaltonSequence(long ID, double value)
Restart an existing Halton sequence from a new initial value.
int32_t startHaltonSequence(int32_t *radix, double value)
Initialize and start a new Halton sequence.
int32_t restartModHaltonSequence(long ID, double tiny)
Restart an existing modified Halton sequence.
double nextHaltonSequencePoint(long ID)
Get the next point in a Halton sequence.