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
00015
00016
00017
00018 float timer(void) {
00019 long elapsed_time;
00020 struct rusage mytime;
00021 getrusage(RUSAGE_SELF,&mytime);
00022
00023
00024 elapsed_time = (mytime.ru_utime.tv_sec * 1000 +
00025 mytime.ru_utime.tv_usec / 1000);
00026
00027
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);
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);
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
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 }