main.c

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <stdarg.h>
00004 #include <strings.h>
00005 #include <unistd.h>
00006 #include <sys/time.h>
00007 #include <sys/resource.h>
00008 #include "svdlib.h"
00009 
00010 enum algorithms{LAS2};
00011 
00012 /***********************************************************************
00013  *                                                                     *
00014  *                        timer()                                      *
00015  *            Returns elapsed cpu time (float, in seconds)             *
00016  *                                                                     *
00017  ***********************************************************************/
00018 float timer(void) {
00019   long elapsed_time;
00020   struct rusage mytime;
00021   getrusage(RUSAGE_SELF,&mytime);
00022  
00023   /* convert elapsed time to milliseconds */
00024   elapsed_time = (mytime.ru_utime.tv_sec * 1000 +
00025                   mytime.ru_utime.tv_usec / 1000);
00026   
00027   /* return elapsed time in seconds */
00028   return((float)elapsed_time/1000.);
00029 }
00030 
00031 static long imin(long a, long b) {return (a < b) ? a : b;}
00032 
00033 static void debug(char *fmt, ...) {
00034   va_list args;
00035   va_start(args, fmt);
00036   vfprintf(stderr, fmt, args);
00037   va_end(args);
00038 }
00039 
00040 static void fatalError(char *fmt, ...) {
00041   va_list args;
00042   va_start(args, fmt);
00043   fprintf(stderr, "ERROR: ");
00044   vfprintf(stderr, fmt, args);
00045   fprintf(stderr, "\a\n");
00046   va_end(args);
00047   exit(1);
00048 }
00049 
00050 void printUsage(char *progname) {
00051   debug("SVD Version %s\n" 
00052         "written by Douglas Rohde based on code adapted from SVDPACKC\n\n", SVDVersion);
00053   debug("usage: %s [options] matrix_file\n", progname);
00054   debug("  -a algorithm   Sets the algorithm to use.  They include:\n"
00055         "       las2 (default)\n"
00056         "  -c infile outfile\n"
00057         "                 Convert a matrix file to a new format (using -r and -w)\n"
00058         "                 Then exit immediately\n"
00059         "  -d dimensions  Desired SVD triples (default is all)\n"
00060         "  -e bound       Minimum magnitude of wanted eigenvalues (1e-30)\n"
00061         "  -k kappa       Accuracy parameter for las2 (1e-6)\n"
00062         "  -i iterations  Algorithm iterations\n"
00063         "  -o file_root   Root of files in which to store resulting U,S,V\n"
00064         "  -r format      Input matrix file format\n"
00065         "       sth       SVDPACK Harwell-Boeing text format\n"
00066         "       st        Sparse text (default)\n"
00067         "       dt        Dense text\n"
00068         "       sb        Sparse binary\n"
00069         "       db        Dense binary\n"
00070         "  -v verbosity   Default 1.  0 for no feedback, 2 for more\n"
00071         "  -w format      Output matrix file format (see -r for formats)\n"
00072         "                   (default is dense text)\n");
00073   exit(1);
00074 }
00075 
00076 
00077 int main(int argc, char *argv[]) {
00078   extern char *optarg;
00079   extern int optind;
00080   int opt;
00081 
00082   SVDRec R = NULL;
00083   SMat A = NULL;
00084 
00085   char transpose = FALSE;
00086   int readFormat = SVD_F_ST;
00087   int writeFormat = SVD_F_DT;
00088   int algorithm = LAS2;
00089   int iterations = 0;
00090   int dimensions = 0;
00091   char *vectorFile = NULL;
00092   double las2end[2] = {-1.0e-30, 1.0e-30};
00093   double kappa = 1e-6;
00094   double exetime;
00095 
00096   while ((opt = getopt(argc, argv, "a:c:d:e:hk:i:o:r:tv:w:")) != -1) {
00097     switch (opt) {
00098     case 'a':
00099       if (!strcasecmp(optarg, "las2"))
00100         algorithm = LAS2;
00101       else fatalError("unknown algorithm: %s", optarg);
00102       break;
00103     case 'c':
00104       if (optind != argc - 1) printUsage(argv[0]);
00105       if (SVDVerbosity > 0) printf("Converting %s to %s\n", optarg, argv[optind]);
00106       if (SVD_IS_SPARSE(readFormat) && SVD_IS_SPARSE(writeFormat)) {
00107         SMat S = svdLoadSparseMatrix(optarg, readFormat);
00108         if (!S) fatalError("failed to read sparse matrix");
00109         if (transpose) {
00110           if (SVDVerbosity > 0) printf("  Transposing the matrix...\n");
00111           S = svdTransposeS(S); /* This leaks memory. */
00112         }
00113         svdWriteSparseMatrix(S, argv[optind], writeFormat);
00114       } else {
00115         DMat D = svdLoadDenseMatrix(optarg, readFormat);
00116         if (!D) fatalError("failed to read dense matrix");
00117         if (transpose) {
00118           if (SVDVerbosity > 0) printf("  Transposing the matrix...\n");
00119           D = svdTransposeD(D); /* This leaks memory. */
00120         }
00121         svdWriteDenseMatrix(D, argv[optind], writeFormat);
00122       }
00123       exit(0);
00124       break;
00125     case 'd':
00126       dimensions = atoi(optarg);
00127       if (dimensions < 0) fatalError("dimensions must be non-negative");
00128       break;
00129     case 'e':
00130       las2end[1] = atof(optarg);
00131       las2end[0] = -las2end[1];
00132       break;
00133     case 'h':
00134       printUsage(argv[0]);
00135       break;
00136     case 'k':
00137       kappa = atof(optarg);
00138       break;
00139     case 'i':
00140       iterations = atoi(optarg);
00141       break;
00142     case 'o':
00143       vectorFile = optarg;
00144       break;
00145     case 'r':
00146       if (!strcasecmp(optarg, "sth")) {
00147         readFormat = SVD_F_STH;
00148       } else if (!strcasecmp(optarg, "st")) {
00149         readFormat = SVD_F_ST;
00150       } else if (!strcasecmp(optarg, "dt")) {
00151         readFormat = SVD_F_DT;
00152       } else if (!strcasecmp(optarg, "sb")) {
00153         readFormat = SVD_F_SB;
00154       } else if (!strcasecmp(optarg, "db")) {
00155         readFormat = SVD_F_DB;
00156       } else fatalError("bad file format: %s", optarg);
00157       break;
00158     case 't':
00159       transpose = TRUE;
00160       break;
00161     case 'v':
00162       SVDVerbosity = atoi(optarg);
00163       /*if (SVDVerbosity) printf("Verbosity = %ld\n", SVDVerbosity);*/
00164       break;
00165     case 'w':
00166       if (!strcasecmp(optarg, "sth")) {
00167         writeFormat = SVD_F_STH;
00168       } else if (!strcasecmp(optarg, "st")) {
00169         writeFormat = SVD_F_ST;
00170       } else if (!strcasecmp(optarg, "dt")) {
00171         writeFormat = SVD_F_DT;
00172       } else if (!strcasecmp(optarg, "sb")) {
00173         writeFormat = SVD_F_SB;
00174       } else if (!strcasecmp(optarg, "db")) {
00175         writeFormat = SVD_F_DB;
00176       } else fatalError("bad file format: %s", optarg);
00177       break;
00178     default: printUsage(argv[0]);
00179     }
00180   }
00181   if (optind != argc - 1) printUsage(argv[0]);
00182 
00183   if (SVDVerbosity > 0) printf("Loading the matrix...\n");
00184   A = svdLoadSparseMatrix(argv[optind], readFormat);
00185   if (!A) fatalError("failed to read sparse matrix.  Did you specify the correct file type with the -r argument?");
00186   if (transpose) {
00187     if (SVDVerbosity > 0) printf("  Transposing the matrix...\n");
00188     SMat T = A;
00189     A = svdTransposeS(A);
00190     svdFreeSMat(T);
00191   }
00192 
00193   if (dimensions <= 0) dimensions = imin(A->rows, A->cols);
00194 
00195   exetime = timer();
00196 
00197   if (SVDVerbosity > 0) printf("Computing the SVD...\n");
00198   if (algorithm == LAS2) {
00199     if (!(R = svdLAS2(A, dimensions, iterations, las2end, kappa)))
00200       fatalError("error in svdLAS2");
00201   } else {
00202     fatalError("unknown algorithm");
00203   }
00204 
00205   exetime = timer() - exetime;
00206   if (SVDVerbosity > 0) {
00207     printf("\nELAPSED CPU TIME          = %6g sec.\n", exetime);
00208     printf("MULTIPLICATIONS BY A      = %6ld\n", 
00209            (SVDCount[SVD_MXV] - R->d) / 2 + R->d);
00210     printf("MULTIPLICATIONS BY A^T    = %6ld\n", 
00211            (SVDCount[SVD_MXV] - R->d) / 2);
00212   }
00213 
00214   if (vectorFile) {
00215     char filename[128];
00216     sprintf(filename, "%s-Ut", vectorFile);
00217     svdWriteDenseMatrix(R->Ut, filename, writeFormat);
00218     sprintf(filename, "%s-S", vectorFile);
00219     svdWriteDenseArray(R->S, R->d, filename, FALSE);
00220     sprintf(filename, "%s-Vt", vectorFile);
00221     svdWriteDenseMatrix(R->Vt, filename, writeFormat);
00222   }
00223   return 0;
00224 }