SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
halton.c File Reference

Detailed Description

Implementation of Halton and modified Halton sequences.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, R. Soliday, H. Shang, Y. Wang

Definition in file halton.c.

#include "mdb.h"

Go to the source code of this file.

Functions

int32_t startHaltonSequence (int32_t *radix, double value)
 Initialize and start a new Halton sequence.
 
int32_t restartHaltonSequence (long ID, double value)
 Restart an existing Halton sequence from a new initial value.
 
double nextHaltonSequencePoint (long ID)
 Get the next point in a Halton sequence.
 
int32_t power (int32_t a, int32_t b, int32_t m)
 
int32_t primes ()
 
int inhalt (int dimen, int atmost, double tiny, double *quasi)
 
int32_t startModHaltonSequence (int32_t *radix, double tiny)
 Start a modified Halton sequence.
 
int32_t restartModHaltonSequence (long ID, double tiny)
 Restart an existing modified Halton sequence.
 
int32_t generateModHaltSequence (double *quasi, double *dq, double *wq, long ID)
 
double nextModHaltonSequencePoint (long ID)
 Retrieve the next point from the modified Halton sequence.
 

Function Documentation

◆ generateModHaltSequence()

int32_t generateModHaltSequence ( double * quasi,
double * dq,
double * wq,
long ID )

Definition at line 550 of file halton.c.

550 {
551 int32_t i = (int32_t)ID, j, k, ytemp[40], xtemp[40], ltemp, mtemp;
552 double t, f, g, h;
553 /* generate quasi one compoment at a time using radix prime[k] for
554 component k */
555
556 t = iprime[i];
557 f = 1.0 - quasi[i];
558 g = 1.0;
559 h = t;
560 while ((f - h) < eError)
561 /* this checks whether q+h>1-eError */
562 {
563 g = h;
564 h *= t;
565 }
566 quasi[i] = g + h - f;
567
568 k = 0;
569 mtemp = nextPoint[i];
570 ltemp = prime[i];
571
572 while (mtemp != 0) {
573 ytemp[k] = mtemp % ltemp;
574 mtemp = mtemp / ltemp;
575 k++;
576 }
577 /*generating Optimal primitive root */
578 for (j = 0; j < k; j++) {
579 /* xtemp[j] = (ytemp[j]*power(primroots[i/10][i%10], nextn%ltemp, ltemp))%ltemp; */
580 xtemp[j] = (warnockOpt[i] * power(primroots[i / 10][i % 10], ytemp[j], ltemp)) % ltemp;
581 xtemp[j] -= ytemp[j];
582 }
583 dq[i] = 0;
584 t = iprime[i];
585 for (j = 0; j < k; j++) {
586 dq[i] += xtemp[j] * t;
587 t *= iprime[i];
588 }
589 dq[i] += quasi[i];
590 /* generating Warnock Optimal sequences */
591 for (j = 0; j < k; j++) {
592 /* if( i%2==0)xtemp[j]= (ytemp[j]*warnockOpt[i])%ltemp;
593 else xtemp[j]= (ytemp[j]*warnockOpt[i]*warnockOpt[i])%ltemp;
594 */
595 xtemp[j] = (ytemp[j] * power(warnockOpt[i], i + 1, ltemp)) % ltemp;
596 /* if(i>=3)
597 xtemp[j]=((prime[i-1]-1)*power(warnockOpt[i],ytemp[j],ltemp))%ltemp;
598 else xtemp[j]= (power(warnockOpt[i],ytemp[j],ltemp))%ltemp;
599 */
600 xtemp[j] -= ytemp[j];
601 }
602
603 wq[i] = 0;
604 t = iprime[i];
605 for (j = 0; j < k; j++) {
606 wq[i] += xtemp[j] * t;
607 t *= iprime[i];
608 }
609 wq[i] += quasi[i];
610
611 nextPoint[i]++;
612
613 return (0);
614}

◆ inhalt()

int inhalt ( int dimen,
int atmost,
double tiny,
double * quasi )

Definition at line 468 of file halton.c.

468 {
469 double delta;
470 int i /*,m*/;
471
472 /* check dimen */
473 sDim = dimen;
474 if (sDim < 1 || sDim > 1000)
475 return (-1);
476
477 /* compute and check tolerance*/
478
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))
482 return (-2);
483
484 /* now compute first vector */
485
486 /*m=1;*/
487 for (i = 0; i < sDim; i++) {
488 iprime[i] = 1.0 / prime[i];
489 quasi[i] = iprime[i];
490 /*m=i*prime[i];*/
491 nextPoint[i] = 2;
492 }
493
494 /*printf("largest prime=%d, %d \n",prime[sDim-1], m);*/
495
496 return 0;
497}

◆ nextHaltonSequencePoint()

double nextHaltonSequencePoint ( long ID)

Get the next point in a Halton sequence.

Computes the next value in the specified Halton sequence.

Parameters
IDThe sequence ID.
Returns
The next point in the sequence, or -1 if the ID is invalid.

Definition at line 107 of file halton.c.

107 {
108 double r, f, value;
109
110 ID -= 1;
111
112 if (ID > sequencesInUse || ID < 0)
113 return -1;
114
115 f = 1 - lastPointValue[ID];
116 r = 1. / R[ID];
117 while (f <= r)
118 r = r / R[ID];
119 value = lastPointValue[ID] + (R[ID] + 1) * r - 1;
120 lastPointValue[ID] = value;
121 return value;
122}

◆ nextModHaltonSequencePoint()

double nextModHaltonSequencePoint ( long ID)

Retrieve the next point from the modified Halton sequence.

Generates and returns the next value for a given sequence ID in the modified Halton sequence.

Parameters
IDThe sequence ID.
Returns
The next point in the modified Halton sequence.

Definition at line 624 of file halton.c.

624 {
625 static double *dq = NULL, *wq = NULL;
626
627 ID -= 1;
628 if (dq == NULL)
629 dq = malloc(sizeof(*dq) * sDim);
630 if (wq == NULL)
631 wq = malloc(sizeof(*wq) * sDim);
632 if (!modSequenceInUse) {
633 fprintf(stderr, "ModHalton sequence not started.\n");
634 exit(1);
635 }
636 if (ID < 0 || ID > sDim - 1) {
637 fprintf(stderr, "Invalid ID (%ld) provided\n", ID);
638 exit(1);
639 }
640 generateModHaltSequence(quasi, dq, wq, ID);
641
642 return wq[ID];
643}

◆ power()

int32_t power ( int32_t a,
int32_t b,
int32_t m )

Definition at line 444 of file halton.c.

444 {
445 int32_t i, c = 1;
446 for (i = 0; i < b; i++)
447 c = (c * a) % m;
448 return c;
449}

◆ primes()

int32_t primes ( )

Definition at line 451 of file halton.c.

451 {
452 int32_t i, j, a[MAX_D + 1];
453 for (a[1] = 0, i = 2; i <= MAX_D; i++)
454 a[i] = 1;
455 for (i = 2; i <= MAX_D / 2; i++)
456 for (j = 2; j <= MAX_D / i; j++)
457 a[i * j] = 0;
458 for (i = 1, j = 0; i <= MAX_D; i++) {
459 if (a[i]) {
460 prime[j] = i;
461 iprime[j] = (double)i;
462 j++;
463 }
464 }
465 return j;
466}

◆ restartHaltonSequence()

int32_t restartHaltonSequence ( long ID,
double value )

Restart an existing Halton sequence from a new initial value.

Resets the specified Halton sequence so that subsequent calls will continue from the given initial value.

Parameters
IDThe sequence ID to restart.
valueThe new starting value.
Returns
1 on success, or -1 if the ID is invalid.

Definition at line 88 of file halton.c.

88 {
89 ID -= 1;
90
91 if (ID > sequencesInUse || ID < 0)
92 return -1;
93
94 lastPointValue[ID] = value;
95
96 return 1;
97}

◆ restartModHaltonSequence()

int32_t restartModHaltonSequence ( long ID,
double tiny )

Restart an existing modified Halton sequence.

Resets internal parameters so that the modified Halton sequence restarts.

Parameters
IDThe sequence ID.
tinyA small tolerance value.
Returns
1 on success, or -1 on failure.

Definition at line 538 of file halton.c.

538 {
539 int32_t dimen = 12, total_points = 100000;
540
541 tiny = 0;
542 if (inhalt(dimen, total_points, tiny, quasi) < 0) {
543 fprintf(stderr, "Unable to start modHalton sequence.\n");
544 return -1;
545 }
546
547 return 1;
548}

◆ startHaltonSequence()

int32_t startHaltonSequence ( int32_t * radix,
double value )

Initialize and start a new Halton sequence.

Initializes a new Halton sequence with the given radix and starting value. If the provided radix is not a prime or is non-positive, a suitable prime is chosen.

Parameters
radixPointer to an integer specifying the desired prime radix. If non-positive, a prime is chosen automatically.
valueThe starting value for the sequence.
Returns
The sequence ID (1-based) on success, or 0 on failure.

Definition at line 38 of file halton.c.

38 {
39 int32_t ID;
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)))))
45 return 0;
46 if (*radix > 0) {
47 if (is_prime(*radix) != 1)
48 return 0;
49 R[sequencesInUse] = *radix;
50 ID = sequencesInUse;
51 } else {
52 /* generate a new, unique prime number for use as the radix */
53 long i, passed;
54 if ((ID = sequencesInUse) < N_SEQ_PREDEFINED)
55 /* try one of the favored values */
56 *radix = Rvalues[ID];
57 else
58 *radix = 2;
59 passed = 0;
60 while (!passed) {
61 passed = 1;
62 for (i = 0; i < sequencesInUse; i++) {
63 if (R[i] == *radix) {
64 passed = 0;
65 (*radix)++;
66 while (is_prime(*radix) != 1)
67 (*radix)++;
68 }
69 }
70 }
71 R[ID] = *radix;
72 }
73 lastPointValue[ID] = value;
74 sequencesInUse++;
75 return ID + 1;
76}
int64_t is_prime(int64_t number)
Determine if a number is prime.
Definition factorize.c:26

◆ startModHaltonSequence()

int32_t startModHaltonSequence ( int32_t * radix,
double tiny )

Start a modified Halton sequence.

Initializes a modified Halton sequence with predefined prime bases and internal parameters.

Parameters
radixPointer to an integer to store the chosen prime radix.
tinyA small tolerance value.
Returns
The sequence ID (1-based) on success, or -1 on failure.

Definition at line 508 of file halton.c.

508 {
509 int32_t modID, dimen = 12, total_points = 100000;
510 tiny = 0;
511 /* check dimen*/
512 if (!modSequenceInUse) {
513 /*generate primes
514 primes(); */
515 /* commented out primes generation and put it as global constants to skip generate it every time when start the sequence*/
516 if (!quasi)
517 quasi = malloc(sizeof(*quasi) * sDim);
518 if (inhalt(dimen, total_points, tiny, quasi) < 0) {
519 fprintf(stderr, "Unable to start modHalton sequence.\n");
520 return -1;
521 }
522 }
523 modID = modSequenceInUse;
524 *radix = prime[modID];
525 modSequenceInUse++;
526 return modID + 1;
527}