00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <stdarg.h>
00004 #include <string.h>
00005 #include <errno.h>
00006 #include <math.h>
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009
00010
00011 #if defined(_WIN32)
00012 #include <Winsock2.h>
00013 #define popen(X,Y) _popen(X,Y)
00014 #define pclose(X) _pclose(X)
00015 #elif defined(linux) || defined(__linux) || defined(__CYGWIN__) || defined(__APPLE__)
00016 #include <netinet/in.h>
00017 #else
00018 #error "Unsupported OS\n"
00019 #endif
00020
00021
00022 #include "svdlib.h"
00023 #include "svdutil.h"
00024
00025 #define BUNZIP2 "bzip2 -d"
00026 #define BZIP2 "bzip2 -1"
00027 #define UNZIP "gzip -d"
00028 #define ZIP "gzip -1"
00029 #define COMPRESS "compress"
00030
00031 #define MAX_FILENAME 512
00032 #define MAX_PIPES 64
00033 static FILE *Pipe[MAX_PIPES];
00034 static int numPipes = 0;
00035
00036 long *svd_longArray(long size, char empty, char *name) {
00037 long *a;
00038 if (empty) a = (long *) calloc(size, sizeof(long));
00039 else a = (long *) malloc(size * sizeof(long));
00040 if (!a) {
00041 perror(name);
00042
00043 }
00044 return a;
00045 }
00046
00047 double *svd_doubleArray(long size, char empty, char *name) {
00048 double *a;
00049 if (empty) a = (double *) calloc(size, sizeof(double));
00050 else a = (double *) malloc(size * sizeof(double));
00051 if (!a) {
00052 perror(name);
00053
00054 }
00055 return a;
00056 }
00057
00058 void svd_beep(void) {
00059 fputc('\a', stderr);
00060 fflush(stderr);
00061 }
00062
00063 void svd_debug(char *fmt, ...) {
00064 va_list args;
00065 va_start(args, fmt);
00066 vfprintf(stderr, fmt, args);
00067 va_end(args);
00068 }
00069
00070 void svd_error(char *fmt, ...) {
00071 va_list args;
00072 va_start(args, fmt);
00073 svd_beep();
00074 fprintf(stderr, "ERROR: ");
00075 vfprintf(stderr, fmt, args);
00076 fprintf(stderr, "\n");
00077 va_end(args);
00078 }
00079
00080 void svd_fatalError(char *fmt, ...) {
00081 va_list args;
00082 va_start(args, fmt);
00083 svd_beep();
00084 fprintf(stderr, "ERROR: ");
00085 vfprintf(stderr, fmt, args);
00086 fprintf(stderr, "\a\n");
00087 va_end(args);
00088 exit(1);
00089 }
00090
00091 static void registerPipe(FILE *p) {
00092 if (numPipes >= MAX_PIPES) svd_error("Too many pipes open");
00093 Pipe[numPipes++] = p;
00094 }
00095
00096 static char isPipe(FILE *p) {
00097 int i;
00098 for (i = 0; i < numPipes && Pipe[i] != p; i++);
00099 if (i == numPipes) return FALSE;
00100 Pipe[i] = Pipe[--numPipes];
00101 return TRUE;
00102 }
00103
00104 static FILE *openPipe(char *pipeName, char *mode) {
00105 FILE *pipe;
00106 fflush(stdout);
00107 if ((pipe = popen(pipeName, mode))) registerPipe(pipe);
00108 return pipe;
00109 }
00110
00111 static FILE *readZippedFile(char *command, char *fileName) {
00112 char buf[MAX_FILENAME];
00113 sprintf(buf, "%s < %s 2>/dev/null", command, fileName);
00114 return openPipe(buf, "r");
00115 }
00116
00117 FILE *svd_fatalReadFile(char *filename) {
00118 FILE *file;
00119 if (!(file = svd_readFile(filename)))
00120 svd_fatalError("couldn't read the file %s", filename);
00121 return file;
00122 }
00123
00124 static int stringEndsIn(char *s, char *t) {
00125 int ls = strlen(s);
00126 int lt = strlen(t);
00127 if (ls < lt) return FALSE;
00128 return (strcmp(s + ls - lt, t)) ? FALSE : TRUE;
00129 }
00130
00131
00132 FILE *svd_readFile(char *fileName) {
00133 char fileBuf[MAX_FILENAME];
00134 struct stat statbuf;
00135
00136
00137 if (!strcmp(fileName, "-"))
00138 return stdin;
00139
00140
00141 if (fileName[0] == '|')
00142 return openPipe(fileName + 1, "r");
00143
00144
00145 if (stringEndsIn(fileName, ".gz") || stringEndsIn(fileName, ".Z")) {
00146 if (!stat(fileName, &statbuf))
00147 return readZippedFile(UNZIP, fileName);
00148 return NULL;
00149 }
00150
00151 if (stringEndsIn(fileName, ".bz") || stringEndsIn(fileName, ".bz2")) {
00152 if (!stat(fileName, &statbuf))
00153 return readZippedFile(BUNZIP2, fileName);
00154 return NULL;
00155 }
00156
00157 if (!stat(fileName, &statbuf))
00158 return fopen(fileName, "r");
00159
00160 sprintf(fileBuf, "%s.gz", fileName);
00161 if (!stat(fileBuf, &statbuf))
00162 return readZippedFile(UNZIP, fileBuf);
00163
00164 sprintf(fileBuf, "%s.Z", fileName);
00165 if (!stat(fileBuf, &statbuf))
00166 return readZippedFile(UNZIP, fileBuf);
00167
00168 sprintf(fileBuf, "%s.bz2", fileName);
00169 if (!stat(fileBuf, &statbuf))
00170 return readZippedFile(BUNZIP2, fileBuf);
00171
00172 sprintf(fileBuf, "%s.bz", fileName);
00173 if (!stat(fileBuf, &statbuf))
00174 return readZippedFile(BUNZIP2, fileBuf);
00175
00176 return NULL;
00177 }
00178
00179 static FILE *writeZippedFile(char *fileName, char append) {
00180 char buf[MAX_FILENAME];
00181 const char *op = (append) ? ">>" : ">";
00182 if (stringEndsIn(fileName, ".bz2") || stringEndsIn(fileName, ".bz"))
00183 sprintf(buf, "%s %s \"%s\"", BZIP2, op, fileName);
00184 else if (stringEndsIn(fileName, ".Z"))
00185 sprintf(buf, "%s %s \"%s\"", COMPRESS, op, fileName);
00186 else
00187 sprintf(buf, "%s %s \"%s\"", ZIP, op, fileName);
00188 return openPipe(buf, "w");
00189 }
00190
00191 FILE *svd_writeFile(char *fileName, char append) {
00192
00193 if (!strcmp(fileName, "-"))
00194 return stdout;
00195
00196
00197 if (fileName[0] == '|')
00198 return openPipe(fileName + 1, "w");
00199
00200
00201 if (stringEndsIn(fileName, ".gz") || stringEndsIn(fileName, ".Z") ||
00202 stringEndsIn(fileName, ".bz") || stringEndsIn(fileName, ".bz2"))
00203 return writeZippedFile(fileName, append);
00204 return (append) ? fopen(fileName, "a") : fopen(fileName, "w");
00205 }
00206
00207
00208 void svd_closeFile(FILE *file) {
00209 if (file == stdin || file == stdout) return;
00210 if (isPipe(file)) pclose(file);
00211 else fclose(file);
00212 }
00213
00214
00215 char svd_readBinInt(FILE *file, int *val) {
00216 int x;
00217 if (fread(&x, sizeof(int), 1, file) == 1) {
00218 *val = ntohl(x);
00219 return FALSE;
00220 }
00221 return TRUE;
00222 }
00223
00224
00225 char svd_readBinFloat(FILE *file, float *val) {
00226 int x;
00227 float y;
00228 if (fread(&x, sizeof(int), 1, file) == 1) {
00229 x = ntohl(x);
00230 y = *((float *) &x);
00231 *val = y;
00232 return FALSE;
00233 }
00234 return TRUE;
00235 }
00236
00237 char svd_writeBinInt(FILE *file, int x) {
00238 int y = htonl(x);
00239 if (fwrite(&y, sizeof(int), 1, file) != 1) return TRUE;
00240 return FALSE;
00241 }
00242
00243
00244 char svd_writeBinFloat(FILE *file, float r) {
00245 int y = htonl(*((int *) &r));
00246 if (fwrite(&y, sizeof(int), 1, file) != 1) return TRUE;
00247 return FALSE;
00248 }
00249
00250
00251
00252
00253
00254 double svd_fsign(double a, double b) {
00255 if ((a>=0.0 && b>=0.0) || (a<0.0 && b<0.0))return(a);
00256 else return -a;
00257 }
00258
00259
00260
00261
00262 double svd_dmax(double a, double b) {
00263 return (a > b) ? a : b;
00264 }
00265
00266
00267
00268
00269 double svd_dmin(double a, double b) {
00270 return (a < b) ? a : b;
00271 }
00272
00273
00274
00275
00276 long svd_imax(long a, long b) {
00277 return (a > b) ? a : b;
00278 }
00279
00280
00281
00282
00283 long svd_imin(long a, long b) {
00284 return (a < b) ? a : b;
00285 }
00286
00287
00288
00289
00290
00291 void svd_dscal(long n, double da, double *dx, long incx) {
00292 long i;
00293
00294 if (n <= 0 || incx == 0) return;
00295 if (incx < 0) dx += (-n+1) * incx;
00296 for (i=0; i < n; i++) {
00297 *dx *= da;
00298 dx += incx;
00299 }
00300 return;
00301 }
00302
00303
00304
00305
00306
00307 void svd_datx(long n, double da, double *dx, long incx, double *dy, long incy) {
00308 long i;
00309
00310 if (n <= 0 || incx == 0 || incy == 0 || da == 0.0) return;
00311 if (incx == 1 && incy == 1)
00312 for (i=0; i < n; i++) *dy++ = da * (*dx++);
00313
00314 else {
00315 if (incx < 0) dx += (-n+1) * incx;
00316 if (incy < 0) dy += (-n+1) * incy;
00317 for (i=0; i < n; i++) {
00318 *dy = da * (*dx);
00319 dx += incx;
00320 dy += incy;
00321 }
00322 }
00323 return;
00324 }
00325
00326
00327
00328
00329
00330 void svd_dcopy(long n, double *dx, long incx, double *dy, long incy) {
00331 long i;
00332
00333 if (n <= 0 || incx == 0 || incy == 0) return;
00334 if (incx == 1 && incy == 1)
00335 for (i=0; i < n; i++) *dy++ = *dx++;
00336
00337 else {
00338 if (incx < 0) dx += (-n+1) * incx;
00339 if (incy < 0) dy += (-n+1) * incy;
00340 for (i=0; i < n; i++) {
00341 *dy = *dx;
00342 dx += incx;
00343 dy += incy;
00344 }
00345 }
00346 return;
00347 }
00348
00349
00350
00351
00352
00353 double svd_ddot(long n, double *dx, long incx, double *dy, long incy) {
00354 long i;
00355 double dot_product;
00356
00357 if (n <= 0 || incx == 0 || incy == 0) return(0.0);
00358 dot_product = 0.0;
00359 if (incx == 1 && incy == 1)
00360 for (i=0; i < n; i++) dot_product += (*dx++) * (*dy++);
00361 else {
00362 if (incx < 0) dx += (-n+1) * incx;
00363 if (incy < 0) dy += (-n+1) * incy;
00364 for (i=0; i < n; i++) {
00365 dot_product += (*dx) * (*dy);
00366 dx += incx;
00367 dy += incy;
00368 }
00369 }
00370 return(dot_product);
00371 }
00372
00373
00374
00375
00376
00377 void svd_daxpy (long n, double da, double *dx, long incx, double *dy, long incy) {
00378 long i;
00379
00380 if (n <= 0 || incx == 0 || incy == 0 || da == 0.0) return;
00381 if (incx == 1 && incy == 1)
00382 for (i=0; i < n; i++) {
00383 *dy += da * (*dx++);
00384 dy++;
00385 }
00386 else {
00387 if (incx < 0) dx += (-n+1) * incx;
00388 if (incy < 0) dy += (-n+1) * incy;
00389 for (i=0; i < n; i++) {
00390 *dy += da * (*dx);
00391 dx += incx;
00392 dy += incy;
00393 }
00394 }
00395 return;
00396 }
00397
00398
00399
00400
00401 void svd_dsort2(long igap, long n, double *array1, double *array2) {
00402 double temp;
00403 long i, j, index;
00404
00405 if (!igap) return;
00406 else {
00407 for (i = igap; i < n; i++) {
00408 j = i - igap;
00409 index = i;
00410 while (j >= 0 && array1[j] > array1[index]) {
00411 temp = array1[j];
00412 array1[j] = array1[index];
00413 array1[index] = temp;
00414 temp = array2[j];
00415 array2[j] = array2[index];
00416 array2[index] = temp;
00417 j -= igap;
00418 index = j + igap;
00419 }
00420 }
00421 }
00422 svd_dsort2(igap/2,n,array1,array2);
00423 }
00424
00425
00426
00427
00428
00429 void svd_dswap(long n, double *dx, long incx, double *dy, long incy) {
00430 long i;
00431 double dtemp;
00432
00433 if (n <= 0 || incx == 0 || incy == 0) return;
00434 if (incx == 1 && incy == 1) {
00435 for (i=0; i < n; i++) {
00436 dtemp = *dy;
00437 *dy++ = *dx;
00438 *dx++ = dtemp;
00439 }
00440 }
00441 else {
00442 if (incx < 0) dx += (-n+1) * incx;
00443 if (incy < 0) dy += (-n+1) * incy;
00444 for (i=0; i < n; i++) {
00445 dtemp = *dy;
00446 *dy = *dx;
00447 *dx = dtemp;
00448 dx += incx;
00449 dy += incy;
00450 }
00451 }
00452 }
00453
00454
00455
00456
00457
00458 long svd_idamax(long n, double *dx, long incx) {
00459 long ix,i,imax;
00460 double dtemp, dmax;
00461
00462 if (n < 1) return(-1);
00463 if (n == 1) return(0);
00464 if (incx == 0) return(-1);
00465
00466 if (incx < 0) ix = (-n+1) * incx;
00467 else ix = 0;
00468 imax = ix;
00469 dx += ix;
00470 dmax = fabs(*dx);
00471 for (i=1; i < n; i++) {
00472 ix += incx;
00473 dx += incx;
00474 dtemp = fabs(*dx);
00475 if (dtemp > dmax) {
00476 dmax = dtemp;
00477 imax = ix;
00478 }
00479 }
00480 return(imax);
00481 }
00482
00483
00484
00485
00486
00487
00488 void svd_opb(SMat A, double *x, double *y, double *temp) {
00489 long i, j, end;
00490 long *pointr = A->pointr, *rowind = A->rowind;
00491 double *value = A->value;
00492 long n = A->cols;
00493
00494 SVDCount[SVD_MXV] += 2;
00495 memset(y, 0, n * sizeof(double));
00496 for (i = 0; i < A->rows; i++) temp[i] = 0.0;
00497
00498 for (i = 0; i < A->cols; i++) {
00499 end = pointr[i+1];
00500 for (j = pointr[i]; j < end; j++)
00501 temp[rowind[j]] += value[j] * (*x);
00502 x++;
00503 }
00504 for (i = 0; i < A->cols; i++) {
00505 end = pointr[i+1];
00506 for (j = pointr[i]; j < end; j++)
00507 *y += value[j] * temp[rowind[j]];
00508 y++;
00509 }
00510 return;
00511 }
00512
00513
00514
00515
00516
00517 void svd_opa(SMat A, double *x, double *y) {
00518 long end, i, j;
00519 long *pointr = A->pointr, *rowind = A->rowind;
00520 double *value = A->value;
00521
00522 SVDCount[SVD_MXV]++;
00523 memset(y, 0, A->rows * sizeof(double));
00524
00525 for (i = 0; i < A->cols; i++) {
00526 end = pointr[i+1];
00527 for (j = pointr[i]; j < end; j++)
00528 y[rowind[j]] += value[j] * x[i];
00529 }
00530 return;
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 double svd_random2(long *iy) {
00565 static long m2 = 0;
00566 static long ia, ic, mic;
00567 static double halfm, s;
00568
00569
00570 if (!m2) {
00571 m2 = 1 << (8 * (int)sizeof(int) - 2);
00572 halfm = m2;
00573
00574
00575
00576 ia = 8 * (long)(halfm * atan(1.0) / 8.0) + 5;
00577 ic = 2 * (long)(halfm * (0.5 - sqrt(3.0)/6.0)) + 1;
00578 mic = (m2-ic) + m2;
00579
00580
00581 s = 0.5 / halfm;
00582 }
00583
00584
00585 *iy = *iy * ia;
00586
00587
00588 if (*iy > mic) *iy = (*iy - m2) - m2;
00589
00590 *iy = *iy + ic;
00591
00592
00593
00594 if (*iy / 2 > m2) *iy = (*iy - m2) - m2;
00595
00596
00597 if (*iy < 0) *iy = (*iy + m2) + m2;
00598
00599 return((double)(*iy) * s);
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 double svd_pythag(double a, double b) {
00617 double p, r, s, t, u, temp;
00618
00619 p = svd_dmax(fabs(a), fabs(b));
00620 if (p != 0.0) {
00621 temp = svd_dmin(fabs(a), fabs(b)) / p;
00622 r = temp * temp;
00623 t = 4.0 + r;
00624 while (t != 4.0) {
00625 s = r / t;
00626 u = 1.0 + 2.0 * s;
00627 p *= u;
00628 temp = s / u;
00629 r *= temp * temp;
00630 t = 4.0 + r;
00631 }
00632 }
00633 return(p);
00634 }
00635