1 /*<html><pre> -<a href="index.htm#TOC"
2 >-------------------------------</a><a name="TOP">-</a>
3
4 random.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.h"
12 #include "random.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.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 */
qh_argv_to_command(int argc,char * argv[],char * command,int max_size)41 int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
42 int i, remaining;
43 char *s;
44 *command= '\0'; /* max_size > 0 */
45
46 if (argc) {
47 if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
48 || (s= strrchr( argv[0], '/')))
49 s++;
50 else
51 s= argv[0];
52 if ((int)strlen(s) < max_size) /* WARN64 */
53 strcpy(command, s);
54 else
55 goto error_argv;
56 if ((s= strstr(command, ".EXE"))
57 || (s= strstr(command, ".exe")))
58 *s= '\0';
59 }
60 for (i=1; i < argc; i++) {
61 s= argv[i];
62 remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2; /* WARN64 */
63 if (!*s || strchr(s, ' ')) {
64 char *t= command + strlen(command);
65 remaining -= 2;
66 if (remaining < 0) {
67 goto error_argv;
68 }
69 *t++= ' ';
70 *t++= '"';
71 while (*s) {
72 if (*s == '"') {
73 if (--remaining < 0)
74 goto error_argv;
75 *t++= '\\';
76 }
77 *t++= *s++;
78 }
79 *t++= '"';
80 *t= '\0';
81 }else if (remaining < 0) {
82 goto error_argv;
83 }else {
84 strcat(command, " ");
85 strcat(command, s);
86 }
87 }
88 return 1;
89
90 error_argv:
91 return 0;
92 } /* argv_to_command */
93
94 /*-<a href="qh-globa.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 */
qh_argv_to_command_size(int argc,char * argv[])107 int qh_argv_to_command_size(int argc, char *argv[]) {
108 int count= 1; /* null-terminator if argc==0 */
109 int i;
110 char *s;
111
112 for (i=0; i<argc; i++){
113 count += (int)strlen(argv[i]) + 1; /* WARN64 */
114 if (i>0 && strchr(argv[i], ' ')) {
115 count += 2; /* quote delimiters */
116 for (s=argv[i]; *s; s++) {
117 if (*s == '"') {
118 count++;
119 }
120 }
121 }
122 }
123 return count;
124 } /* argv_to_command_size */
125
126 /*-<a href="qh-geom.htm#TOC"
127 >-------------------------------</a><a name="rand">-</a>
128
129 qh_rand()
130 qh_srand( 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.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 int qh_last_random= 1; /* define as global variable instead of using qh */
146
147 #define qh_rand_a 16807
148 #define qh_rand_m 2147483647
149 #define qh_rand_q 127773 /* m div a */
150 #define qh_rand_r 2836 /* m mod a */
151
qh_rand(void)152 int qh_rand(void) {
153 int lo, hi, test;
154 int seed= qh_last_random;
155
156 hi= seed / qh_rand_q; /* seed div q */
157 lo= seed % qh_rand_q; /* seed mod q */
158 test= qh_rand_a * lo - qh_rand_r * hi;
159 if (test > 0)
160 seed= test;
161 else
162 seed= test + qh_rand_m;
163 qh_last_random= seed;
164 /* seed= seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax; for testing */
165 /* seed= qh_RANDOMmax; for testing */
166 return seed;
167 } /* rand */
168
qh_srand(int seed)169 void qh_srand(int seed) {
170 if (seed < 1)
171 qh_last_random= 1;
172 else if (seed >= qh_rand_m)
173 qh_last_random= qh_rand_m - 1;
174 else
175 qh_last_random= seed;
176 } /* qh_srand */
177
178 /*-<a href="qh-geom.htm#TOC"
179 >-------------------------------</a><a name="randomfactor">-</a>
180
181 qh_randomfactor( scale, offset )
182 return a random factor r * scale + offset
183
184 notes:
185 qh.RANDOMa/b are defined in global.c
186 */
qh_randomfactor(realT scale,realT offset)187 realT qh_randomfactor(realT scale, realT offset) {
188 realT randr;
189
190 randr= qh_RANDOMint;
191 return randr * scale + offset;
192 } /* randomfactor */
193
194 /*-<a href="qh-geom.htm#TOC"
195 >-------------------------------</a><a name="randommatrix">-</a>
196
197 qh_randommatrix( buffer, dim, rows )
198 generate a random dim X dim matrix in range [-1,1]
199 assumes buffer is [dim+1, dim]
200
201 returns:
202 sets buffer to random numbers
203 sets rows to rows of buffer
204 sets row[dim] as scratch row
205 */
qh_randommatrix(realT * buffer,int dim,realT ** rows)206 void qh_randommatrix(realT *buffer, int dim, realT **rows) {
207 int i, k;
208 realT **rowi, *coord, realr;
209
210 coord= buffer;
211 rowi= rows;
212 for (i=0; i < dim; i++) {
213 *(rowi++)= coord;
214 for (k=0; k < dim; k++) {
215 realr= qh_RANDOMint;
216 *(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
217 }
218 }
219 *rowi= coord;
220 } /* randommatrix */
221
222 /*-<a href="qh-globa.htm#TOC"
223 >-------------------------------</a><a name="strtol">-</a>
224
225 qh_strtol( s, endp) qh_strtod( s, endp)
226 internal versions of strtol() and strtod()
227 does not skip trailing spaces
228 notes:
229 some implementations of strtol()/strtod() skip trailing spaces
230 */
qh_strtod(const char * s,char ** endp)231 double qh_strtod(const char *s, char **endp) {
232 double result;
233
234 result= strtod(s, endp);
235 if (s < (*endp) && (*endp)[-1] == ' ')
236 (*endp)--;
237 return result;
238 } /* strtod */
239
qh_strtol(const char * s,char ** endp)240 int qh_strtol(const char *s, char **endp) {
241 int result;
242
243 result= (int) strtol(s, endp, 10); /* WARN64 */
244 if (s< (*endp) && (*endp)[-1] == ' ')
245 (*endp)--;
246 return result;
247 } /* strtol */
248