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