random_r.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*<html><pre> -<a href="index_r.htm#TOC"
  2. >-------------------------------</a><a name="TOP">-</a>
  3. random_r.c and utilities
  4. Park & Miller's minimimal standard random number generator
  5. argc/argv conversion
  6. Used by rbox. Do not use 'qh'
  7. */
  8. #include "libqhull_r.h"
  9. #include "random_r.h"
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #ifdef _MSC_VER /* Microsoft Visual C++ -- warning level 4 */
  14. #pragma warning( disable : 4706) /* assignment within conditional function */
  15. #pragma warning( disable : 4996) /* function was declared deprecated(strcpy, localtime, etc.) */
  16. #endif
  17. /*-<a href="qh-globa_r.htm#TOC"
  18. >-------------------------------</a><a name="argv_to_command">-</a>
  19. qh_argv_to_command( argc, argv, command, max_size )
  20. build command from argc/argv
  21. max_size is at least
  22. returns:
  23. a space-delimited string of options (just as typed)
  24. returns false if max_size is too short
  25. notes:
  26. silently removes
  27. makes option string easy to input and output
  28. matches qh_argv_to_command_size
  29. argc may be 0
  30. */
  31. int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
  32. int i, remaining;
  33. char *s;
  34. *command= '\0'; /* max_size > 0 */
  35. if (argc) {
  36. if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
  37. || (s= strrchr( argv[0], '/')))
  38. s++;
  39. else
  40. s= argv[0];
  41. if ((int)strlen(s) < max_size) /* WARN64 */
  42. strcpy(command, s);
  43. else
  44. goto error_argv;
  45. if ((s= strstr(command, ".EXE"))
  46. || (s= strstr(command, ".exe")))
  47. *s= '\0';
  48. }
  49. for (i=1; i < argc; i++) {
  50. s= argv[i];
  51. remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2; /* WARN64 */
  52. if (!*s || strchr(s, ' ')) {
  53. char *t= command + strlen(command);
  54. remaining -= 2;
  55. if (remaining < 0) {
  56. goto error_argv;
  57. }
  58. *t++= ' ';
  59. *t++= '"';
  60. while (*s) {
  61. if (*s == '"') {
  62. if (--remaining < 0)
  63. goto error_argv;
  64. *t++= '\\';
  65. }
  66. *t++= *s++;
  67. }
  68. *t++= '"';
  69. *t= '\0';
  70. }else if (remaining < 0) {
  71. goto error_argv;
  72. }else {
  73. strcat(command, " ");
  74. strcat(command, s);
  75. }
  76. }
  77. return 1;
  78. error_argv:
  79. return 0;
  80. } /* argv_to_command */
  81. /*-<a href="qh-globa_r.htm#TOC"
  82. >-------------------------------</a><a name="argv_to_command_size">-</a>
  83. qh_argv_to_command_size( argc, argv )
  84. return size to allocate for qh_argv_to_command()
  85. notes:
  86. only called from rbox with qh_errexit not enabled
  87. caller should report error if returned size is less than 1
  88. argc may be 0
  89. actual size is usually shorter
  90. */
  91. int qh_argv_to_command_size(int argc, char *argv[]) {
  92. int count= 1; /* null-terminator if argc==0 */
  93. int i;
  94. char *s;
  95. for (i=0; i<argc; i++){
  96. count += (int)strlen(argv[i]) + 1; /* WARN64 */
  97. if (i>0 && strchr(argv[i], ' ')) {
  98. count += 2; /* quote delimiters */
  99. for (s=argv[i]; *s; s++) {
  100. if (*s == '"') {
  101. count++;
  102. }
  103. }
  104. }
  105. }
  106. return count;
  107. } /* argv_to_command_size */
  108. /*-<a href="qh-geom_r.htm#TOC"
  109. >-------------------------------</a><a name="rand">-</a>
  110. qh_rand()
  111. qh_srand(qh, seed )
  112. generate pseudo-random number between 1 and 2^31 -2
  113. notes:
  114. For qhull and rbox, called from qh_RANDOMint(),etc. [user_r.h]
  115. From Park & Miller's minimal standard random number generator
  116. Communications of the ACM, 31:1192-1201, 1988.
  117. Does not use 0 or 2^31 -1
  118. this is silently enforced by qh_srand()
  119. Can make 'Rn' much faster by moving qh_rand to qh_distplane
  120. */
  121. /* Global variables and constants */
  122. #define qh_rand_a 16807
  123. #define qh_rand_m 2147483647
  124. #define qh_rand_q 127773 /* m div a */
  125. #define qh_rand_r 2836 /* m mod a */
  126. int qh_rand(qhT *qh) {
  127. int lo, hi, test;
  128. int seed= qh->last_random;
  129. hi= seed / qh_rand_q; /* seed div q */
  130. lo= seed % qh_rand_q; /* seed mod q */
  131. test= qh_rand_a * lo - qh_rand_r * hi;
  132. if (test > 0)
  133. seed= test;
  134. else
  135. seed= test + qh_rand_m;
  136. qh->last_random= seed;
  137. /* seed= seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */
  138. /* seed= qh_RANDOMmax; for testing */
  139. return seed;
  140. } /* rand */
  141. void qh_srand(qhT *qh, int seed) {
  142. if (seed < 1)
  143. qh->last_random= 1;
  144. else if (seed >= qh_rand_m)
  145. qh->last_random= qh_rand_m - 1;
  146. else
  147. qh->last_random= seed;
  148. } /* qh_srand */
  149. /*-<a href="qh-geom_r.htm#TOC"
  150. >-------------------------------</a><a name="randomfactor">-</a>
  151. qh_randomfactor(qh, scale, offset )
  152. return a random factor r * scale + offset
  153. notes:
  154. qh.RANDOMa/b are defined in global_r.c
  155. qh_RANDOMint requires 'qh'
  156. */
  157. realT qh_randomfactor(qhT *qh, realT scale, realT offset) {
  158. realT randr;
  159. randr= qh_RANDOMint;
  160. return randr * scale + offset;
  161. } /* randomfactor */
  162. /*-<a href="qh-geom_r.htm#TOC"
  163. >-------------------------------</a><a name="randommatrix">-</a>
  164. qh_randommatrix(qh, buffer, dim, rows )
  165. generate a random dim X dim matrix in range [-1,1]
  166. assumes buffer is [dim+1, dim]
  167. returns:
  168. sets buffer to random numbers
  169. sets rows to rows of buffer
  170. sets row[dim] as scratch row
  171. notes:
  172. qh_RANDOMint requires 'qh'
  173. */
  174. void qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **rows) {
  175. int i, k;
  176. realT **rowi, *coord, realr;
  177. coord= buffer;
  178. rowi= rows;
  179. for (i=0; i < dim; i++) {
  180. *(rowi++)= coord;
  181. for (k=0; k < dim; k++) {
  182. realr= qh_RANDOMint;
  183. *(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
  184. }
  185. }
  186. *rowi= coord;
  187. } /* randommatrix */
  188. /*-<a href="qh-globa_r.htm#TOC"
  189. >-------------------------------</a><a name="strtol">-</a>
  190. qh_strtol( s, endp) qh_strtod( s, endp)
  191. internal versions of strtol() and strtod()
  192. does not skip trailing spaces
  193. notes:
  194. some implementations of strtol()/strtod() skip trailing spaces
  195. */
  196. double qh_strtod(const char *s, char **endp) {
  197. double result;
  198. result= strtod(s, endp);
  199. if (s < (*endp) && (*endp)[-1] == ' ')
  200. (*endp)--;
  201. return result;
  202. } /* strtod */
  203. int qh_strtol(const char *s, char **endp) {
  204. int result;
  205. result= (int) strtol(s, endp, 10); /* WARN64 */
  206. if (s< (*endp) && (*endp)[-1] == ' ')
  207. (*endp)--;
  208. return result;
  209. } /* strtol */