00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00045 #include <fastlib/fastlib.h>
00046 #include "quicsvd.h"
00047
00048 const fx_entry_doc quicsvd_main_entries[] = {
00049 {"A_in", FX_REQUIRED, FX_STR, NULL,
00050 " File consists of matrix A to be decomposed A = U S VT. \n"},
00051 {"relErr", FX_PARAM, FX_DOUBLE, NULL,
00052 " Target relative error |A|-|A'|/|A|, default = 0.1.\n"},
00053 {"U_out", FX_PARAM, FX_STR, NULL,
00054 " File to hold matrix U.\n"},
00055 {"s_out", FX_PARAM, FX_STR, NULL,
00056 " File to hold the singular values vector s.\n"},
00057 {"VT_out", FX_PARAM, FX_STR, NULL,
00058 " File to hold matrix VT (V transposed).\n"},
00059 {"SVT_out", FX_PARAM, FX_STR, NULL,
00060 " File to hold matrix S * VT (the dimension reduced data).\n"},
00061 {"lasvd", FX_PARAM, FX_STR, NULL,
00062 " Use this parameter to compare running time to that of la::SVDInit().\n"},
00063 {"quicsvd_time", FX_TIMER, FX_CUSTOM, NULL,
00064 " time to run the QUIC-SVD algorithm.\n"},
00065 {"lasvd_time", FX_TIMER, FX_CUSTOM, NULL,
00066 " time to run the SVD algorithm from LAPACK.\n"},
00067 {"actualErr", FX_RESULT, FX_DOUBLE, NULL,
00068 " actual relative norm error.\n"},
00069 {"dimension", FX_RESULT, FX_INT, NULL,
00070 " the reduced dimension of the data.\n"},
00071 FX_ENTRY_DOC_DONE
00072 };
00073
00074 const fx_submodule_doc quicsvd_main_submodules[] = {
00075 FX_SUBMODULE_DOC_DONE
00076 };
00077
00078 const fx_module_doc quicsvd_main_doc = {
00079 quicsvd_main_entries, quicsvd_main_submodules,
00080 "This is a program calculating an approximated Singular "
00081 "Value Decomposition using QUIC-SVD method.\n"
00082 };
00083
00084 double norm(const Matrix& A) {
00085 double s = 0;
00086 for (int i = 0; i < A.n_cols(); i++) {
00087 Vector col;
00088 A.MakeColumnVector(i, &col);
00089 s += math::Sqr(la::LengthEuclidean(col));
00090 }
00091 return sqrt(s);
00092 }
00093
00094 int main(int argc, char* argv[]) {
00095 fx_init(argc, argv, &quicsvd_main_doc);
00096
00097 Matrix A, U, VT;
00098 Vector s;
00099
00100
00101 const char* A_in = fx_param_str(NULL, "A_in", NULL);
00102
00103 printf("Loading data ... ");
00104 fflush(stdout);
00105 data::Load(A_in, &A);
00106 printf("n_rows = %d, n_cols = %d, done.\n", A.n_rows(), A.n_cols());
00107
00108
00109 const double targetRelErr = fx_param_double(NULL, "relErr", 0.1);
00110
00111 printf("QUIC-SVD start ... ");
00112 fflush(stdout);
00113 fx_timer_start(NULL, "quicsvd_time");
00114
00115 double actualErr = QuicSVD::SVDInit(A, targetRelErr, &s, &U, &VT);
00116 fx_timer_stop(NULL, "quicsvd_time");
00117 printf("stop.\n");
00118
00119 fx_result_double(NULL, "actualErr", actualErr);
00120 fx_result_int(NULL, "dimension", s.length());
00121
00122 if (fx_param_exists(NULL, "U_out"))
00123 data::Save(fx_param_str(NULL, "U_out", NULL), U);
00124
00125
00126
00127 if (fx_param_exists(NULL, "s_out")) {
00128 Matrix S;
00129 S.AliasColVector(s);
00130 data::Save(fx_param_str(NULL, "s_out", NULL), S);
00131 }
00132
00133
00134
00135 if (fx_param_exists(NULL, "VT_out"))
00136 data::Save(fx_param_str(NULL, "VT_out", NULL), VT);
00137
00138
00139
00140 if (fx_param_exists(NULL, "SVT_out")) {
00141 la::ScaleRows(s, &VT);
00142 data::Save(fx_param_str(NULL, "SVT_out", NULL), VT);
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 if (fx_param_exists(NULL, "lasvd")) {
00167 s.Destruct();
00168 U.Destruct();
00169 VT.Destruct();
00170 printf("LAPACK-SVD start ... ");
00171 fflush(stdout);
00172 fx_timer_start(NULL, "lasvd_time");
00173
00174 la::SVDInit(A, &s, &U, &VT);
00175 fx_timer_stop(NULL, "lasvd_time");
00176 printf("stop.\n");
00177 }
00178
00179 fx_done(NULL);
00180 }