aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/qhull/libqhull_r/random_r.c
blob: 7eecd30e0940ecc5ed3d21ef1fd66ffa8a0b6d51 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
/*<html><pre>  -<a                             href="index_r.htm#TOC"
  >-------------------------------</a><a name="TOP">-</a>

   random_r.c and utilities
     Park & Miller's minimimal standard random number generator
     argc/argv conversion

     Used by rbox.  Do not use 'qh' 
*/

#include "libqhull_r.h"
#include "random_r.h"

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef _MSC_VER  /* Microsoft Visual C++ -- warning level 4 */
#pragma warning( disable : 4706)  /* assignment within conditional function */
#pragma warning( disable : 4996)  /* function was declared deprecated(strcpy, localtime, etc.) */
#endif

/*-<a                             href="qh-globa_r.htm#TOC"
  >-------------------------------</a><a name="argv_to_command">-</a>

  qh_argv_to_command( argc, argv, command, max_size )

    build command from argc/argv
    max_size is at least

  returns:
    a space-delimited string of options (just as typed)
    returns false if max_size is too short

  notes:
    silently removes
    makes option string easy to input and output
    matches qh_argv_to_command_size
    argc may be 0
*/
int qh_argv_to_command(int argc, char *argv[], char* command, int max_size) {
  int i, remaining;
  char *s;
  *command= '\0';  /* max_size > 0 */

  if (argc) {
    if ((s= strrchr( argv[0], '\\')) /* get filename w/o .exe extension */
    || (s= strrchr( argv[0], '/')))
        s++;
    else
        s= argv[0];
    if ((int)strlen(s) < max_size)   /* WARN64 */
        strcpy(command, s);
    else
        goto error_argv;
    if ((s= strstr(command, ".EXE"))
    ||  (s= strstr(command, ".exe")))
        *s= '\0';
  }
  for (i=1; i < argc; i++) {
    s= argv[i];
    remaining= max_size - (int)strlen(command) - (int)strlen(s) - 2;   /* WARN64 */
    if (!*s || strchr(s, ' ')) {
      char *t= command + strlen(command);
      remaining -= 2;
      if (remaining < 0) {
        goto error_argv;
      }
      *t++= ' ';
      *t++= '"';
      while (*s) {
        if (*s == '"') {
          if (--remaining < 0)
            goto error_argv;
          *t++= '\\';
        }
        *t++= *s++;
      }
      *t++= '"';
      *t= '\0';
    }else if (remaining < 0) {
      goto error_argv;
    }else {
      strcat(command, " ");
      strcat(command, s);
    }
  }
  return 1;

error_argv:
  return 0;
} /* argv_to_command */

/*-<a                             href="qh-globa_r.htm#TOC"
  >-------------------------------</a><a name="argv_to_command_size">-</a>

  qh_argv_to_command_size( argc, argv )

    return size to allocate for qh_argv_to_command()

  notes:
    only called from rbox with qh_errexit not enabled
    caller should report error if returned size is less than 1
    argc may be 0
    actual size is usually shorter
*/
int qh_argv_to_command_size(int argc, char *argv[]) {
    int count= 1; /* null-terminator if argc==0 */
    int i;
    char *s;

    for (i=0; i<argc; i++){
      count += (int)strlen(argv[i]) + 1;   /* WARN64 */
      if (i>0 && strchr(argv[i], ' ')) {
        count += 2;  /* quote delimiters */
        for (s=argv[i]; *s; s++) {
          if (*s == '"') {
            count++;
          }
        }
      }
    }
    return count;
} /* argv_to_command_size */

/*-<a                             href="qh-geom_r.htm#TOC"
  >-------------------------------</a><a name="rand">-</a>

  qh_rand()
  qh_srand(qh, seed )
    generate pseudo-random number between 1 and 2^31 -2

  notes:
    For qhull and rbox, called from qh_RANDOMint(),etc. [user_r.h]

    From Park & Miller's minimal standard random number generator
      Communications of the ACM, 31:1192-1201, 1988.
    Does not use 0 or 2^31 -1
      this is silently enforced by qh_srand()
    Can make 'Rn' much faster by moving qh_rand to qh_distplane
*/

/* Global variables and constants */

#define qh_rand_a 16807
#define qh_rand_m 2147483647
#define qh_rand_q 127773  /* m div a */
#define qh_rand_r 2836    /* m mod a */

int qh_rand(qhT *qh) {
    int lo, hi, test;
    int seed= qh->last_random;

    hi= seed / qh_rand_q;  /* seed div q */
    lo= seed % qh_rand_q;  /* seed mod q */
    test= qh_rand_a * lo - qh_rand_r * hi;
    if (test > 0)
        seed= test;
    else
        seed= test + qh_rand_m;
    qh->last_random= seed;
    /* seed= seed < qh_RANDOMmax/2 ? 0 : qh_RANDOMmax;  for testing */
    /* seed= qh_RANDOMmax;  for testing */
    return seed;
} /* rand */

void qh_srand(qhT *qh, int seed) {
    if (seed < 1)
        qh->last_random= 1;
    else if (seed >= qh_rand_m)
        qh->last_random= qh_rand_m - 1;
    else
        qh->last_random= seed;
} /* qh_srand */

/*-<a                             href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="randomfactor">-</a>

qh_randomfactor(qh, scale, offset )
  return a random factor r * scale + offset

notes:
  qh.RANDOMa/b are defined in global_r.c
  qh_RANDOMint requires 'qh'
*/
realT qh_randomfactor(qhT *qh, realT scale, realT offset) {
    realT randr;

    randr= qh_RANDOMint;
    return randr * scale + offset;
} /* randomfactor */

/*-<a                             href="qh-geom_r.htm#TOC"
>-------------------------------</a><a name="randommatrix">-</a>

  qh_randommatrix(qh, buffer, dim, rows )
    generate a random dim X dim matrix in range [-1,1]
    assumes buffer is [dim+1, dim]

  returns:
    sets buffer to random numbers
    sets rows to rows of buffer
    sets row[dim] as scratch row

  notes:
    qh_RANDOMint requires 'qh'
*/
void qh_randommatrix(qhT *qh, realT *buffer, int dim, realT **rows) {
    int i, k;
    realT **rowi, *coord, realr;

    coord= buffer;
    rowi= rows;
    for (i=0; i < dim; i++) {
        *(rowi++)= coord;
        for (k=0; k < dim; k++) {
            realr= qh_RANDOMint;
            *(coord++)= 2.0 * realr/(qh_RANDOMmax+1) - 1.0;
        }
    }
    *rowi= coord;
} /* randommatrix */

/*-<a                             href="qh-globa_r.htm#TOC"
  >-------------------------------</a><a name="strtol">-</a>

  qh_strtol( s, endp) qh_strtod( s, endp)
    internal versions of strtol() and strtod()
    does not skip trailing spaces
  notes:
    some implementations of strtol()/strtod() skip trailing spaces
*/
double qh_strtod(const char *s, char **endp) {
  double result;

  result= strtod(s, endp);
  if (s < (*endp) && (*endp)[-1] == ' ')
    (*endp)--;
  return result;
} /* strtod */

int qh_strtol(const char *s, char **endp) {
  int result;

  result= (int) strtol(s, endp, 10);     /* WARN64 */
  if (s< (*endp) && (*endp)[-1] == ' ')
    (*endp)--;
  return result;
} /* strtol */