File Coverage

svdutil.c
Criterion Covered Total %
statement 142 299 47.4
branch 100 240 41.6
condition n/a
subroutine n/a
pod n/a
total 242 539 44.9


line stmt bran cond sub pod time code
1             #include
2             /*
3             Copyright © 2002, University of Tennessee Research Foundation.
4             All rights reserved.
5              
6             Redistribution and use in source and binary forms, with or without
7             modification, are permitted provided that the following conditions are met:
8              
9             * Redistributions of source code must retain the above copyright notice, this
10             list of conditions and the following disclaimer.
11              
12             Redistributions in binary form must reproduce the above copyright notice,
13             this list of conditions and the following disclaimer in the documentation
14             and/or other materials provided with the distribution.
15              
16             * Neither the name of the University of Tennessee nor the names of its
17             contributors may be used to endorse or promote products derived from this
18             software without specific prior written permission.
19              
20             THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21             AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22             IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23             ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24             LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25             CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26             SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27             INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28             CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29             ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30             POSSIBILITY OF SUCH DAMAGE.
31             */
32             /*
33             * Modified by moocow for PDL::SVDLIBC distribution
34             */
35              
36             #include
37             #include
38             #include
39             #include
40             #include
41             #include
42             #include
43             #include
44             #if 0
45             /* Mon, Tue, 24 Nov 2015 09:42:30 +0100 moocow
46             * + disable netinet/in.h for win32 (why is it even here anyways?)
47             * - probably for ntohl() and htonl(); gnu libc docs say:
48             * uint32_t ntohl (uint32_t NETLONG)
49             * converts the 'uint32_t' integer NETLONG from network byte order to host byte order;
50             * This is used for IPv4 Internet addresses.
51             * * this is only used by svd_(read|write)Bin(Int|Float)() functions, which
52             * we don't need here; replacing calls with dummy macros
53             */
54             #include
55             #else
56             #define svdlibc_ntohl(x) x
57             #define svdlibc_htonl(x) x
58             #endif
59             #include "svdlib.h"
60             #include "svdutil.h"
61              
62             #define BUNZIP2 "bzip2 -d"
63             #define BZIP2 "bzip2 -1"
64             #define UNZIP "gzip -d"
65             #define ZIP "gzip -1"
66             #define COMPRESS "compress"
67              
68             #define MAX_FILENAME 512
69             #define MAX_PIPES 64
70             static FILE *Pipe[MAX_PIPES];
71             static int numPipes = 0;
72              
73 6           __SVDLIBC_LONG *svd_longArray(__SVDLIBC_LONG size, char empty, char *name) {
74             __SVDLIBC_LONG *a;
75 6 100         if (empty) a = (__SVDLIBC_LONG *) calloc(size, sizeof(__SVDLIBC_LONG));
76 3           else a = (__SVDLIBC_LONG *) malloc(size * sizeof(__SVDLIBC_LONG));
77 6 50         if (!a) {
78 0           perror(name);
79             /* exit(errno); */
80             }
81 6           return a;
82             }
83              
84 243           double *svd_doubleArray(__SVDLIBC_LONG size, char empty, char *name) {
85             double *a;
86 243 100         if (empty) a = (double *) calloc(size, sizeof(double));
87 193           else a = (double *) malloc(size * sizeof(double));
88 243 50         if (!a) {
89 0           perror(name);
90             /* exit(errno); */
91             }
92 243           return a;
93             }
94              
95 0           void svd_beep(void) {
96 0           fputc('\a', stderr);
97 0           fflush(stderr);
98 0           }
99              
100 0           void svd_debug(char *fmt, ...) {
101             va_list args;
102 0           va_start(args, fmt);
103 0           vfprintf(stderr, fmt, args);
104 0           va_end(args);
105 0           }
106              
107 0           void svd_error(char *fmt, ...) {
108             va_list args;
109 0           va_start(args, fmt);
110 0           svd_beep();
111 0           fprintf(stderr, "ERROR: ");
112 0           vfprintf(stderr, fmt, args);
113 0           fprintf(stderr, "\n");
114 0           va_end(args);
115 0           }
116              
117 0           void svd_fatalError(char *fmt, ...) {
118             va_list args;
119 0           va_start(args, fmt);
120 0           svd_beep();
121 0           fprintf(stderr, "ERROR: ");
122 0           vfprintf(stderr, fmt, args);
123 0           fprintf(stderr, "\a\n");
124 0           va_end(args);
125 0           exit(1);
126             }
127              
128 0           static void registerPipe(FILE *p) {
129 0 0         if (numPipes >= MAX_PIPES) svd_error("Too many pipes open");
130 0           Pipe[numPipes++] = p;
131 0           }
132              
133 0           static char isPipe(FILE *p) {
134             int i;
135 0 0         for (i = 0; i < numPipes && Pipe[i] != p; i++);
    0          
136 0 0         if (i == numPipes) return FALSE;
137 0           Pipe[i] = Pipe[--numPipes];
138 0           return TRUE;
139             }
140              
141 0           static FILE *openPipe(char *pipeName, char *mode) {
142             FILE *pipe;
143 0           fflush(stdout);
144 0 0         if ((pipe = popen(pipeName, mode))) registerPipe(pipe);
145 0           return pipe;
146             }
147              
148 0           static FILE *readZippedFile(char *command, char *fileName) {
149             char buf[MAX_FILENAME];
150 0           sprintf(buf, "%s < %s 2>/dev/null", command, fileName);
151 0           return openPipe(buf, "r");
152             }
153              
154 0           FILE *svd_fatalReadFile(char *filename) {
155             FILE *file;
156 0 0         if (!(file = svd_readFile(filename)))
157 0           svd_fatalError("couldn't read the file %s", filename);
158 0           return file;
159             }
160              
161 0           static int stringEndsIn(char *s, char *t) {
162 0           int ls = strlen(s);
163 0           int lt = strlen(t);
164 0 0         if (ls < lt) return FALSE;
165 0           return (strcmp(s + ls - lt, t)) ? FALSE : TRUE;
166             }
167              
168             /* Will silently return NULL if file couldn't be opened */
169 0           FILE *svd_readFile(char *fileName) {
170             char fileBuf[MAX_FILENAME];
171             struct stat statbuf;
172              
173             /* Special file name */
174 0 0         if (!strcmp(fileName, "-"))
175 0           return stdin;
176            
177             /* If it is a pipe */
178 0 0         if (fileName[0] == '|')
179 0           return openPipe(fileName + 1, "r");
180              
181             /* Check if already ends in .gz or .Z and assume compressed */
182 0 0         if (stringEndsIn(fileName, ".gz") || stringEndsIn(fileName, ".Z")) {
    0          
183 0 0         if (!stat(fileName, &statbuf))
184 0           return readZippedFile(UNZIP, fileName);
185 0           return NULL;
186             }
187             /* Check if already ends in .bz or .bz2 and assume compressed */
188 0 0         if (stringEndsIn(fileName, ".bz") || stringEndsIn(fileName, ".bz2")) {
    0          
189 0 0         if (!stat(fileName, &statbuf))
190 0           return readZippedFile(BUNZIP2, fileName);
191 0           return NULL;
192             }
193             /* Try just opening normally */
194 0 0         if (!stat(fileName, &statbuf))
195 0           return fopen(fileName, "r");
196             /* Try adding .gz */
197 0           sprintf(fileBuf, "%s.gz", fileName);
198 0 0         if (!stat(fileBuf, &statbuf))
199 0           return readZippedFile(UNZIP, fileBuf);
200             /* Try adding .Z */
201 0           sprintf(fileBuf, "%s.Z", fileName);
202 0 0         if (!stat(fileBuf, &statbuf))
203 0           return readZippedFile(UNZIP, fileBuf);
204             /* Try adding .bz2 */
205 0           sprintf(fileBuf, "%s.bz2", fileName);
206 0 0         if (!stat(fileBuf, &statbuf))
207 0           return readZippedFile(BUNZIP2, fileBuf);
208             /* Try adding .bz */
209 0           sprintf(fileBuf, "%s.bz", fileName);
210 0 0         if (!stat(fileBuf, &statbuf))
211 0           return readZippedFile(BUNZIP2, fileBuf);
212              
213 0           return NULL;
214             }
215              
216 0           static FILE *writeZippedFile(char *fileName, char append) {
217             char buf[MAX_FILENAME];
218 0 0         const char *op = (append) ? ">>" : ">";
219 0 0         if (stringEndsIn(fileName, ".bz2") || stringEndsIn(fileName, ".bz"))
    0          
220 0           sprintf(buf, "%s %s \"%s\"", BZIP2, op, fileName);
221 0 0         else if (stringEndsIn(fileName, ".Z"))
222 0           sprintf(buf, "%s %s \"%s\"", COMPRESS, op, fileName);
223             else
224 0           sprintf(buf, "%s %s \"%s\"", ZIP, op, fileName);
225 0           return openPipe(buf, "w");
226             }
227              
228 0           FILE *svd_writeFile(char *fileName, char append) {
229             /* Special file name */
230 0 0         if (!strcmp(fileName, "-"))
231 0           return stdout;
232            
233             /* If it is a pipe */
234 0 0         if (fileName[0] == '|')
235 0           return openPipe(fileName + 1, "w");
236              
237             /* Check if ends in .gz, .Z, .bz, .bz2 */
238 0 0         if (stringEndsIn(fileName, ".gz") || stringEndsIn(fileName, ".Z") ||
239 0 0         stringEndsIn(fileName, ".bz") || stringEndsIn(fileName, ".bz2"))
240 0           return writeZippedFile(fileName, append);
241 0 0         return (append) ? fopen(fileName, "a") : fopen(fileName, "w");
242             }
243              
244             /* Could be a file or a stream. */
245 0           void svd_closeFile(FILE *file) {
246 0 0         if (file == stdin || file == stdout) return;
    0          
247 0 0         if (isPipe(file)) pclose(file);
248 0           else fclose(file);
249             }
250              
251              
252 0           char svd_readBinInt(FILE *file, int *val) {
253             int x;
254 0 0         if (fread(&x, sizeof(int), 1, file) == 1) {
255 0           *val = svdlibc_ntohl(x); //-- moo: disable ntohl() for PDL::SVDLIBC
256 0           return FALSE;
257             }
258 0           return TRUE;
259             }
260              
261             /* This reads a float in network order and converts to a real in host order. */
262 0           char svd_readBinFloat(FILE *file, float *val) {
263             int x;
264             float y;
265 0 0         if (fread(&x, sizeof(int), 1, file) == 1) {
266 0           x = svdlibc_ntohl(x); //-- moo: disable ntohl() for PDL::SVDLIBC
267 0           y = *((float *) &x);
268 0           *val = y;
269 0           return FALSE;
270             }
271 0           return TRUE;
272             }
273              
274 0           char svd_writeBinInt(FILE *file, int x) {
275 0           int y = svdlibc_htonl(x); //-- moo: disable htonl() for PDL::SVDLIBC
276 0 0         if (fwrite(&y, sizeof(int), 1, file) != 1) return TRUE;
277 0           return FALSE;
278             }
279              
280             /* This takes a real in host order and writes a float in network order. */
281 0           char svd_writeBinFloat(FILE *file, float r) {
282 0           int y = svdlibc_htonl(*((int *) &r)); //-- moo: disable htonl() for PDL::SVDLIBC
283 0 0         if (fwrite(&y, sizeof(int), 1, file) != 1) return TRUE;
284 0           return FALSE;
285             }
286              
287              
288             /**************************************************************
289             * returns |a| if b is positive; else fsign returns -|a| *
290             **************************************************************/
291 180           double svd_fsign(double a, double b) {
292 180 50         if ((a>=0.0 && b>=0.0) || (a<0.0 && b<0.0))return(a);
    100          
    50          
    0          
293 100           else return -a;
294             }
295              
296             /**************************************************************
297             * returns the larger of two double precision numbers *
298             **************************************************************/
299 810           double svd_dmax(double a, double b) {
300 810 100         return (a > b) ? a : b;
301             }
302              
303             /**************************************************************
304             * returns the smaller of two double precision numbers *
305             **************************************************************/
306 860           double svd_dmin(double a, double b) {
307 860 100         return (a < b) ? a : b;
308             }
309              
310             /**************************************************************
311             * returns the larger of two integers *
312             **************************************************************/
313 10           __SVDLIBC_LONG svd_imax(__SVDLIBC_LONG a, __SVDLIBC_LONG b) {
314 10           return (a > b) ? a : b;
315             }
316              
317             /**************************************************************
318             * returns the smaller of two integers *
319             **************************************************************/
320 80           __SVDLIBC_LONG svd_imin(__SVDLIBC_LONG a, __SVDLIBC_LONG b) {
321 80           return (a < b) ? a : b;
322             }
323              
324             /**************************************************************
325             * Function scales a vector by a constant. *
326             * Based on Fortran-77 routine from Linpack by J. Dongarra *
327             **************************************************************/
328 117           void svd_dscal(__SVDLIBC_LONG n, double da, double *dx, __SVDLIBC_LONG incx) {
329             __SVDLIBC_LONG i;
330            
331 117 50         if (n <= 0 || incx == 0) return;
    50          
332 117 50         if (incx < 0) dx += (-n+1) * incx;
333 879 100         for (i=0; i < n; i++) {
334 762           *dx *= da;
335 762           dx += incx;
336             }
337 117           return;
338             }
339              
340             /**************************************************************
341             * function scales a vector by a constant. *
342             * Based on Fortran-77 routine from Linpack by J. Dongarra *
343             **************************************************************/
344 60           void svd_datx(__SVDLIBC_LONG n, double da, double *dx, __SVDLIBC_LONG incx, double *dy, __SVDLIBC_LONG incy) {
345             __SVDLIBC_LONG i;
346            
347 60 50         if (n <= 0 || incx == 0 || incy == 0 || da == 0.0) return;
    50          
    50          
    50          
348 120 50         if (incx == 1 && incy == 1)
    50          
349 480 100         for (i=0; i < n; i++) *dy++ = da * (*dx++);
350            
351             else {
352 0 0         if (incx < 0) dx += (-n+1) * incx;
353 0 0         if (incy < 0) dy += (-n+1) * incy;
354 0 0         for (i=0; i < n; i++) {
355 0           *dy = da * (*dx);
356 0           dx += incx;
357 0           dy += incy;
358             }
359             }
360 60           return;
361             }
362              
363             /**************************************************************
364             * Function copies a vector x to a vector y *
365             * Based on Fortran-77 routine from Linpack by J. Dongarra *
366             **************************************************************/
367 560           void svd_dcopy(__SVDLIBC_LONG n, double *dx, __SVDLIBC_LONG incx, double *dy, __SVDLIBC_LONG incy) {
368             __SVDLIBC_LONG i;
369            
370 560 50         if (n <= 0 || incx == 0 || incy == 0) return;
    50          
    50          
371 1080 50         if (incx == 1 && incy == 1)
    100          
372 4160 100         for (i=0; i < n; i++) *dy++ = *dx++;
373            
374             else {
375 40 50         if (incx < 0) dx += (-n+1) * incx;
376 40 50         if (incy < 0) dy += (-n+1) * incy;
377 260 100         for (i=0; i < n; i++) {
378 220           *dy = *dx;
379 220           dx += incx;
380 220           dy += incy;
381             }
382             }
383 560           return;
384             }
385              
386             /**************************************************************
387             * Function forms the dot product of two vectors. *
388             * Based on Fortran-77 routine from Linpack by J. Dongarra *
389             **************************************************************/
390 364           double svd_ddot(__SVDLIBC_LONG n, double *dx, __SVDLIBC_LONG incx, double *dy, __SVDLIBC_LONG incy) {
391             __SVDLIBC_LONG i;
392             double dot_product;
393            
394 364 50         if (n <= 0 || incx == 0 || incy == 0) return(0.0);
    50          
    50          
395 364           dot_product = 0.0;
396 728 50         if (incx == 1 && incy == 1)
    50          
397 2912 100         for (i=0; i < n; i++) dot_product += (*dx++) * (*dy++);
398             else {
399 0 0         if (incx < 0) dx += (-n+1) * incx;
400 0 0         if (incy < 0) dy += (-n+1) * incy;
401 0 0         for (i=0; i < n; i++) {
402 0           dot_product += (*dx) * (*dy);
403 0           dx += incx;
404 0           dy += incy;
405             }
406             }
407 364           return(dot_product);
408             }
409              
410             /**************************************************************
411             * Constant times a vector plus a vector *
412             * Based on Fortran-77 routine from Linpack by J. Dongarra *
413             **************************************************************/
414 637           void svd_daxpy (__SVDLIBC_LONG n, double da, double *dx, __SVDLIBC_LONG incx, double *dy, __SVDLIBC_LONG incy) {
415             __SVDLIBC_LONG i;
416            
417 637 50         if (n <= 0 || incx == 0 || incy == 0 || da == 0.0) return;
    50          
    50          
    50          
418 1274 50         if (incx == 1 && incy == 1)
    50          
419 5096 100         for (i=0; i < n; i++) {
420 4459           *dy += da * (*dx++);
421 4459           dy++;
422             }
423             else {
424 0 0         if (incx < 0) dx += (-n+1) * incx;
425 0 0         if (incy < 0) dy += (-n+1) * incy;
426 0 0         for (i=0; i < n; i++) {
427 0           *dy += da * (*dx);
428 0           dx += incx;
429 0           dy += incy;
430             }
431             }
432 637           return;
433             }
434              
435             /*********************************************************************
436             * Function sorts array1 and array2 into increasing order for array1 *
437             *********************************************************************/
438 30           void svd_dsort2(__SVDLIBC_LONG igap, __SVDLIBC_LONG n, double *array1, double *array2) {
439             double temp;
440             __SVDLIBC_LONG i, j, index;
441            
442 30 100         if (!igap) return;
443             else {
444 100 100         for (i = igap; i < n; i++) {
445 80           j = i - igap;
446 80           index = i;
447 80 50         while (j >= 0 && array1[j] > array1[index]) {
    50          
448 0           temp = array1[j];
449 0           array1[j] = array1[index];
450 0           array1[index] = temp;
451 0           temp = array2[j];
452 0           array2[j] = array2[index];
453 0           array2[index] = temp;
454 0           j -= igap;
455 0           index = j + igap;
456             }
457             }
458             }
459 20           svd_dsort2(igap/2,n,array1,array2);
460             }
461              
462             /**************************************************************
463             * Function interchanges two vectors *
464             * Based on Fortran-77 routine from Linpack by J. Dongarra *
465             **************************************************************/
466 50           void svd_dswap(__SVDLIBC_LONG n, double *dx, __SVDLIBC_LONG incx, double *dy, __SVDLIBC_LONG incy) {
467             __SVDLIBC_LONG i;
468             double dtemp;
469            
470 50 50         if (n <= 0 || incx == 0 || incy == 0) return;
    50          
    50          
471 100 50         if (incx == 1 && incy == 1) {
    50          
472 200 100         for (i=0; i < n; i++) {
473 150           dtemp = *dy;
474 150           *dy++ = *dx;
475 150           *dx++ = dtemp;
476             }
477             }
478             else {
479 0 0         if (incx < 0) dx += (-n+1) * incx;
480 0 0         if (incy < 0) dy += (-n+1) * incy;
481 0 0         for (i=0; i < n; i++) {
482 0           dtemp = *dy;
483 0           *dy = *dx;
484 0           *dx = dtemp;
485 0           dx += incx;
486 0           dy += incy;
487             }
488             }
489             }
490              
491             /*****************************************************************
492             * Function finds the index of element having max. absolute value*
493             * based on FORTRAN 77 routine from Linpack by J. Dongarra *
494             *****************************************************************/
495 50           __SVDLIBC_LONG svd_idamax(__SVDLIBC_LONG n, double *dx, __SVDLIBC_LONG incx) {
496             __SVDLIBC_LONG ix,i,imax;
497             double dtemp, dmax;
498            
499 50 50         if (n < 1) return(-1);
500 50 100         if (n == 1) return(0);
501 40 50         if (incx == 0) return(-1);
502            
503 40 50         if (incx < 0) ix = (-n+1) * incx;
504 40           else ix = 0;
505 40           imax = ix;
506 40           dx += ix;
507 40           dmax = fabs(*dx);
508 150 100         for (i=1; i < n; i++) {
509 110           ix += incx;
510 110           dx += incx;
511 110           dtemp = fabs(*dx);
512 110 50         if (dtemp > dmax) {
513 0           dmax = dtemp;
514 0           imax = ix;
515             }
516             }
517 40           return(imax);
518             }
519              
520             /**************************************************************
521             * multiplication of matrix B by vector x, where B = A'A, *
522             * and A is nrow by ncol (nrow >> ncol). Hence, B is of order *
523             * n = ncol (y stores product vector). *
524             **************************************************************/
525 127           void svd_opb(SMat A, double *x, double *y, double *temp) {
526             __SVDLIBC_LONG i, j, end;
527 127           __SVDLIBC_LONG *pointr = A->pointr, *rowind = A->rowind;
528 127           double *value = A->value;
529 127           __SVDLIBC_LONG n = A->cols;
530              
531 127           SVDCount[SVD_MXV] += 2;
532 127           memset(y, 0, n * sizeof(double));
533 889 100         for (i = 0; i < A->rows; i++) temp[i] = 0.0;
534            
535 1016 100         for (i = 0; i < A->cols; i++) {
536 889           end = pointr[i+1];
537 3683 100         for (j = pointr[i]; j < end; j++)
538 2794           temp[rowind[j]] += value[j] * (*x);
539 889           x++;
540             }
541 1016 100         for (i = 0; i < A->cols; i++) {
542 889           end = pointr[i+1];
543 3683 100         for (j = pointr[i]; j < end; j++)
544 2794           *y += value[j] * temp[rowind[j]];
545 889           y++;
546             }
547 127           return;
548             }
549              
550             /***********************************************************
551             * multiplication of matrix A by vector x, where A is *
552             * nrow by ncol (nrow >> ncol). y stores product vector. *
553             ***********************************************************/
554 57           void svd_opa(SMat A, double *x, double *y) {
555             __SVDLIBC_LONG end, i, j;
556 57           __SVDLIBC_LONG *pointr = A->pointr, *rowind = A->rowind;
557 57           double *value = A->value;
558            
559 57           SVDCount[SVD_MXV]++;
560 57           memset(y, 0, A->rows * sizeof(double));
561            
562 456 100         for (i = 0; i < A->cols; i++) {
563 399           end = pointr[i+1];
564 1653 100         for (j = pointr[i]; j < end; j++)
565 1254           y[rowind[j]] += value[j] * x[i];
566             }
567 57           return;
568             }
569              
570              
571             /***********************************************************************
572             * *
573             * random() *
574             * (double precision) *
575             ***********************************************************************/
576             /***********************************************************************
577              
578             Description
579             -----------
580              
581             This is a translation of a Fortran-77 uniform random number
582             generator. The code is based on theory and suggestions given in
583             D. E. Knuth (1969), vol 2. The argument to the function should
584             be initialized to an arbitrary integer prior to the first call to
585             random. The calling program should not alter the value of the
586             argument between subsequent calls to random. Random returns values
587             within the interval (0,1).
588              
589              
590             Arguments
591             ---------
592              
593             (input)
594             iy an integer seed whose value must not be altered by the caller
595             between subsequent calls
596              
597             (output)
598             random a double precision random number between (0,1)
599              
600             ***********************************************************************/
601 70           double svd_random2(__SVDLIBC_LONG *iy) {
602             static __SVDLIBC_LONG m2 = 0;
603             static __SVDLIBC_LONG ia, ic, mic;
604             static double halfm, s;
605              
606             /* If first entry, compute (max int) / 2 */
607 70 100         if (!m2) {
608 1           m2 = 1 << (8 * (int)sizeof(int) - 2);
609 1           halfm = m2;
610              
611             /* compute multiplier and increment for linear congruential
612             * method */
613 1           ia = 8 * (__SVDLIBC_LONG)(halfm * atan(1.0) / 8.0) + 5;
614 1           ic = 2 * (__SVDLIBC_LONG)(halfm * (0.5 - sqrt(3.0)/6.0)) + 1;
615 1           mic = (m2-ic) + m2;
616              
617             /* s is the scale factor for converting to floating point */
618 1           s = 0.5 / halfm;
619             }
620              
621             /* compute next random number */
622 70           *iy = *iy * ia;
623              
624             /* for computers which do not allow integer overflow on addition */
625 70 100         if (*iy > mic) *iy = (*iy - m2) - m2;
626              
627 70           *iy = *iy + ic;
628              
629             /* for computers whose word length for addition is greater than
630             * for multiplication */
631 70 100         if (*iy / 2 > m2) *iy = (*iy - m2) - m2;
632            
633             /* for computers whose integer overflow affects the sign bit */
634 70 100         if (*iy < 0) *iy = (*iy + m2) + m2;
635              
636 70           return((double)(*iy) * s);
637             }
638              
639             /**************************************************************
640             * *
641             * Function finds sqrt(a^2 + b^2) without overflow or *
642             * destructive underflow. *
643             * *
644             **************************************************************/
645             /**************************************************************
646              
647             Funtions used
648             -------------
649              
650             UTILITY dmax, dmin
651              
652             **************************************************************/
653 800           double svd_pythag(double a, double b) {
654             double p, r, s, t, u, temp;
655              
656 800           p = svd_dmax(fabs(a), fabs(b));
657 800 50         if (p != 0.0) {
658 800           temp = svd_dmin(fabs(a), fabs(b)) / p;
659 800           r = temp * temp;
660 800           t = 4.0 + r;
661 2300 100         while (t != 4.0) {
662 1500           s = r / t;
663 1500           u = 1.0 + 2.0 * s;
664 1500           p *= u;
665 1500           temp = s / u;
666 1500           r *= temp * temp;
667 1500           t = 4.0 + r;
668             }
669             }
670 800           return(p);
671             }
672