static void Main(string[] args) { // ***************** File read stuff double[,] Rawdata; double[,] labelsdata; int k = 100; Console.WriteLine("Principal Components Analysis compression\n"); string testFname = args[0]; using (CsvReader reader = new CsvReader(testFname, hasHeaders: false)) { Rawdata = reader.ToMatrix(); } // Create a new PCA object and cacluate eigenvectors // Calls two differnt routines and provides timing SingleValueDecomposition PCA = new SingleValueDecomposition(Rawdata); //Console.WriteLine(" First few eigen Vectors"); /*for (int row = 0; row < 1; row++) * { * for (int col = 0; col < PCA.UAccordreduced.GetLength(1); col++) * { * Console.Write("{0:N4} ", PCA.UAccordreduced[row, col]); * } * Console.WriteLine(); * }*/ // Create submatrix of k eigen vectors double[,] dimreduced = PCA.UAccordreduced.Get(startRow: 0, endRow: PCA.UAccordreduced.GetLength(0), startColumn: 0, endColumn: k); // Re obtain the unchanged input matrix and convert to n x k double [,] projectionData; using (CsvReader reader = new CsvReader(testFname, hasHeaders: false)) { projectionData = reader.ToMatrix(); } projectionData = temputils.utils.FeatureNormalization(projectionData); // Write out Eigen Vectors using (CsvWriter writer = new CsvWriter("Uforoctave.csv")) { writer.Write(PCA.Ureduced); } double[,] FacesZ = PCA.Reduce(projectionData, Dimension: k, eigenVectors: dimreduced); Console.WriteLine("Done Compressing"); double[,] zz = FacesZ.Dot(dimreduced); string filename = "PCAFaces.csv"; using (CsvWriter writer = new CsvWriter(filename)) { writer.Write(FacesZ); } }
private static void svd_truncated_u_test(int m, int n) //****************************************************************************80 // // Purpose: // // SVD_TRUNCATED_U_TEST tests SVD_TRUNCATED_U. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 20 March 2012 // // Author: // // John Burkardt // { int i; int j; Console.WriteLine(""); Console.WriteLine("SVD_TRUNCATED_U_TEST"); Console.WriteLine(" M = " + m + ""); Console.WriteLine(" N = " + n + ""); double[] a = new double[m * n]; double[] un = new double[m * n]; double[] sn = new double[n * n]; double[] v = new double[n * n]; int seed = 123456789; double[] a_save = UniformRNG.r8mat_uniform_01_new(m, n, ref seed); typeMethods.r8mat_print(m, n, a_save, " A:"); for (j = 0; j < n; j++) { for (i = 0; i < m; i++) { a[i + j * m] = a_save[i + j * m]; } } SingleValueDecomposition.svd_truncated_u(m, n, a, ref un, ref sn, ref v); typeMethods.r8mat_print(m, n, un, " UN:"); typeMethods.r8mat_print(n, n, sn, " SN:"); typeMethods.r8mat_print(n, n, v, " V:"); // // Check the factorization by computing A = U * S * V' // for (j = 0; j < n; j++) { for (i = 0; i < m; i++) { a[i + j * m] = 0.0; int k; for (k = 0; k < n; k++) { a[i + j * m] += un[i + k * m] * sn[k + k * n] * v[j + k * n]; } } } double err = 0.0; for (j = 0; j < n; j++) { for (i = 0; i < m; i++) { err = Math.Max(err, Math.Abs(a[i + j * m] - a_save[i + j * m])); } } Console.WriteLine(""); Console.WriteLine(" Maximum error |A - U*S*V'| = " + err + ""); typeMethods.r8mat_print(m, n, a, " Recomputed A = U * S * V':"); }
private static void Main() //****************************************************************************80 // // Purpose: // // MAIN is the main program for SVD_BASIS. // // Discussion: // // SVD_BASIS forms a basis from the SVD of a set of data vectors. // // This program uses the singular value decomposition (SVD) to analyze // a set of data, and extract a number of dominant modes. // // This program is intended as an intermediate application, in // the following situation: // // A) a "high fidelity" or "high resolution" PDE solver is used // to determine many (say N = 500) solutions of a discretized // PDE at various times, or parameter values. Each solution // may be regarded as an M vector. Typically, each solution // involves an M by M linear system, greatly reduced in // complexity because of bandedness or sparsity. // // B) This program is applied to extract L dominant modes from // the N solutions. This is done using the singular value // decomposition of the M by N matrix, each of whose columns // is one of the original solution vectors. // // C) a "reduced order model" program may then attempt to solve // a discretized version of the PDE, using the L dominant // modes as basis vectors. Typically, this means that a dense // L by L linear system will be involved. // // Thus, the program might read in 500 files, and write out // 5 or 10 files of the corresponding size and "shape", representing // the dominant solution modes. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 22 November 2011 // // Author: // // John Burkardt // { const int DATA_FILE_BASE_MAX = 20; bool comment; int comp_num = 0; string data_file = ""; string[] data_file_base = new string[DATA_FILE_BASE_MAX]; int dim_num = 0; int i; int ii; int j; int node_num = 0; Console.WriteLine(""); Console.WriteLine("SVD_BASIS:"); Console.WriteLine(""); Console.WriteLine(" Given a PDE for which:"); Console.WriteLine(" C is the number of components of the solution"); Console.WriteLine(" at any single point,"); Console.WriteLine(" P is the number of points where a solution is given,"); Console.WriteLine(" N is the number of solution vectors,"); Console.WriteLine(" L is the number of modes to be extracted."); Console.WriteLine(""); Console.WriteLine(" Then we let M = C*P be the abstract spatial dimension."); Console.WriteLine(""); Console.WriteLine(" Set up A, the M by N matrix of solution vectors,"); Console.WriteLine(""); Console.WriteLine(" Get A = U * S * V', the singular value decomposition."); Console.WriteLine(""); Console.WriteLine(" The first L columns of U are our modes."); Console.WriteLine(""); // // What is the basis size? // Console.WriteLine(" How many basis vectors (L) are to be extracted?"); int basis_num = Convert.ToInt32(Console.ReadLine()); Console.WriteLine(""); Console.WriteLine(" L = " + basis_num + ""); // // Gather one or more "base" file names. // int data_file_base_num = 0; for (;;) { if (DATA_FILE_BASE_MAX <= data_file_base_num) { Console.WriteLine(""); Console.WriteLine(" No more base file names can be entered."); return; } // // Get the next base file name. // Console.WriteLine(""); Console.WriteLine(" You specify a consecutive sequence of file names"); Console.WriteLine(" by giving the first \"base\" file name."); Console.WriteLine(""); Console.WriteLine(" If there are no more sequences to enter,"); Console.WriteLine(" just hit RETURN."); Console.WriteLine(""); Console.WriteLine(" Enter a new base file name, or $ if done:"); // // CIN won't allow you to enter a blank line! // I just don't have the energy today to replace CIN by GETLINE.... // string file_name = Console.ReadLine(); switch (file_name) { case "$": file_name = " "; break; } if (typeMethods.s_len_trim(file_name) <= 0) { Console.WriteLine(""); Console.WriteLine(" RETURN was entered."); Console.WriteLine(" Presumably, there are no more file sequences."); break; } data_file_base[data_file_base_num] = file_name; data_file_base_num += 1; Console.WriteLine(""); Console.WriteLine(data_file_base_num + ": \"" + file_name + "\""); switch (data_file_base_num) { // // For the very first base file, get the data sizes. // case 1: { TableHeader h = typeMethods.r8mat_header_read(file_name); comp_num = h.m; node_num = h.n; dim_num = comp_num * node_num; Console.WriteLine(""); Console.WriteLine(" According to the first base file,"); Console.WriteLine(" The number of solution components C = " + comp_num + ""); Console.WriteLine(" The number of solution points P = " + node_num + ""); Console.WriteLine(" The \"size\" of each solution M = (C*P) = " + dim_num + ""); // // Idiocy check. L must be less than or equal to M. // if (dim_num < basis_num) { Console.WriteLine(""); Console.WriteLine("SVD_BASIS - Fatal error!"); Console.WriteLine(""); Console.WriteLine(" M < L."); Console.WriteLine(""); Console.WriteLine(" That is, the number of modes requested (L) is greater"); Console.WriteLine(" than the spatial dimension (M)."); Console.WriteLine(" Technically, the program could pad out the answer"); Console.WriteLine(" with L-M zero vectors, but instead, we will stop"); Console.WriteLine(" assuming you made an error, or a misapprehension."); Console.WriteLine(""); Console.WriteLine("SVD_BASIS:"); Console.WriteLine(" Abnormal end of execution."); Console.WriteLine(""); return; } break; } } } // // Count all the data files. // int data_file_num = 0; for (i = 0; i < data_file_base_num; i++) { data_file = data_file_base[i]; for (;;) { if (!File.Exists(data_file)) { break; } data_file_num += 1; Files.file_name_inc_nowrap(ref data_file); } } switch (data_file_num) { case 0: Console.WriteLine(""); Console.WriteLine("SVD_BASIS - Fatal error!"); Console.WriteLine(" There do not seem to be any solution files;"); Console.WriteLine(" that is, files whose names are \"incremented\""); Console.WriteLine(" versions of the first file name."); Console.WriteLine(""); Console.WriteLine(" The first file we looked for was \"" + data_file + "\""); Console.WriteLine(""); Console.WriteLine("SVD_BASIS:"); Console.WriteLine(" Abnormal end of execution."); Console.WriteLine(""); return; } Console.WriteLine(""); Console.WriteLine(" The number of data files N = " + data_file_num + ""); // // Set up an array to hold all the data. // int point_num = data_file_num; Console.WriteLine(""); Console.WriteLine(" The data is stored in an M by N matrix A."); Console.WriteLine(""); Console.WriteLine(" The \"spatial\" dimension M is " + dim_num + ""); Console.WriteLine(" The number of data points N is " + point_num + ""); // // Allocate space for the POINT array. // double[] point = new double[dim_num * point_num]; // // Read the data. // int l = 0; for (ii = 0; ii < data_file_base_num; ii++) { data_file = data_file_base[ii]; for (;;) { if (!File.Exists(data_file)) { break; } double[] table = typeMethods.r8mat_data_read(data_file, comp_num, node_num); int k = 0; for (j = 0; j < node_num; j++) { for (i = 0; i < comp_num; i++) { point[k + l * dim_num] = table[i + j * comp_num]; k += 1; } } l += 1; Files.file_name_inc_nowrap(ref data_file); } } Console.WriteLine(""); Console.WriteLine(" The data has been read into the matrix A."); // //---------------------------------------------------------------------------- // // Compute the SVD of A. // //---------------------------------------------------------------------------- // double[] sval = new double[basis_num]; SingleValueDecomposition.singular_vectors(dim_num, point_num, basis_num, ref point, ref sval); // //---------------------------------------------------------------------------- // // Write the first L left singular vectors (columns of U) to files. // //---------------------------------------------------------------------------- // Console.WriteLine(""); Console.WriteLine("SVD_BASIS:"); Console.WriteLine(" Ready to write the left singular vectors to files."); Console.WriteLine(""); Console.WriteLine(" Do you want comments in the header of the file?"); Console.WriteLine(" (These begin with the \"#\" character.) (Y/N)"); Console.WriteLine(""); Console.WriteLine(" Enter \"Y\" or \"N\":"); char comment_char = Console.ReadLine().ToCharArray()[0]; switch (comment_char) { case 'Y': case 'y': comment = true; break; default: comment = false; break; } string basis_file = "svd_000.txt"; for (j = 0; j < basis_num; j++) { Files.file_name_inc_nowrap(ref basis_file); switch (j + 1) { case 1: Console.WriteLine(""); Console.WriteLine(" Writing first file " + basis_file + ""); break; } if (j + 1 == basis_num) { Console.WriteLine(" Writing last file " + basis_file + ""); } basis_write(basis_file, comp_num, node_num, sval[j], point, comment, uIndex: +0 + j * dim_num); Console.WriteLine(""); Console.WriteLine("SVD_BASIS:"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }
private static void Main(string[] args) //****************************************************************************80 // // Purpose: // // MAIN is the main program for SVD_DEMO. // // Discussion: // // SVD_DEMO demonstrates the singular value decomposition. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 14 September 2006 // // Author: // // John Burkardt // // Usage: // // svd_demo m n // // Command Parameters: // // Command parameter, integer M, N, the number of rows and columns // of the matrix. // // Local Parameters: // // Local, double A[M*N], the matrix whose singular value // decomposition we are investigating. // // Local, double S[M*N], the diagonal factor // in the singular value decomposition of A. // // Local, int SEED, a seed used to define the random number generator. // // Output, double U[M*M], the first orthogonal factor // in the singular value decomposition of A. // // Output, double V[N*N], the second orthogonal factor // in the singular value decomposition of A. // { int j; int seed; string string_; Console.WriteLine(""); Console.WriteLine("SVD_DEMO:"); Console.WriteLine(""); Console.WriteLine(" Demonstrate the singular value decomposition (SVD)"); Console.WriteLine(""); Console.WriteLine(" A real MxN matrix A can be factored as:"); Console.WriteLine(""); Console.WriteLine(" A = U * S * V'"); Console.WriteLine(""); Console.WriteLine(" where"); Console.WriteLine(""); Console.WriteLine(" U = MxM orthogonal,"); Console.WriteLine(" S = MxN zero except for diagonal,"); Console.WriteLine(" V = NxN orthogonal."); Console.WriteLine(""); Console.WriteLine(" The diagonal of S contains only nonnegative numbers"); Console.WriteLine(" and these are arranged in descending order."); // // If M was not on the command line, get it now. // try { string_ = args[0]; } catch (Exception) { Console.WriteLine(""); Console.WriteLine("SVD_DEMO:"); Console.WriteLine(" Please enter the value of M:"); Console.WriteLine(" (Number of rows in matrix A)."); Console.WriteLine(" (We prefer M <= 10!)."); string_ = Console.ReadLine(); } int m = Convert.ToInt32(string_); Console.WriteLine(""); Console.WriteLine(" Matrix row order M = " + m + ""); // // If N was not on the command line, get it now. // try { string_ = args[1]; } catch (Exception) { Console.WriteLine(""); Console.WriteLine("SVD_DEMO:"); Console.WriteLine(" Please enter the value of N:"); Console.WriteLine(" (Number of columns in matrix A)."); Console.WriteLine(" (We prefer N <= 10!)."); string_ = Console.ReadLine(); } int n = Convert.ToInt32(string_); Console.WriteLine(" Matrix column order N = " + n + ""); // // If SEED was not on the command line, use GET_SEED. // try { seed = Convert.ToInt32(args[2]); Console.WriteLine(" Random number SEED = " + seed + ""); Console.WriteLine(" (Chosen by the user.)"); } catch (Exception) { seed = entropyRNG.RNG.nextint(); Console.WriteLine(" Random number SEED = " + seed + ""); Console.WriteLine(" (Chosen by the program.)"); } // // Set aside space for the arrays. // double[] u = new double[m * m]; double[] s = new double[m * n]; double[] v = new double[n * n]; // // Generate the matrix. // Console.WriteLine(""); Console.WriteLine(" We choose a \"random\" matrix A, with integral"); Console.WriteLine(" values between 0 and 10."); double[] a = UniformRNG.r8mat_uniform_01_new(m, n, ref seed); for (j = 0; j < n; j++) { int i; for (i = 0; i < m; i++) { a[i + m * j] = typeMethods.r8_nint(10.0 * a[i + m * j]); } } typeMethods.r8mat_print(m, n, a, " The matrix A:"); // // Get the SVD from LINPACK. // SingleValueDecomposition.r8mat_svd_linpack(m, n, a, ref u, ref s, ref v); // // Print the SVD. // typeMethods.r8mat_print(m, m, u, " The orthogonal factor U:"); typeMethods.r8mat_print(m, n, s, " The diagonal factor S:"); typeMethods.r8mat_print(n, n, v, " The orthogonal factor V:"); // // Check that A = U * S * V'. // SingleValueDecomposition.svd_product_test(m, n, a, u, s, v); // // Compute the norm of the difference between A and the successive // sums of rank one approximants. // Ranking.rank_one_test(m, n, a, u, s, v); // // Actually print the sums of rank one approximants. // Ranking.rank_one_print_test(m, n, a, u, s, v); // // Compute the pseudoinverse. // double[] a_pseudo = PseudoLinear.pseudo_inverse(m, n, u, s, v); typeMethods.r8mat_print(n, m, a_pseudo, " The pseudoinverse of A:"); // // Test A*A+ = I+, A+*A = I+ // PseudoLinear.pseudo_product_test(m, n, a, a_pseudo); // // Demonstrate the use of the pseudoinverse for linear systems. // PseudoLinear.pseudo_linear_solve_test(m, n, a, a_pseudo, ref seed); Console.WriteLine(""); Console.WriteLine("SVD_DEMO:"); Console.WriteLine(" Normal end of execution."); Console.WriteLine(""); }