private static SVDRec svdLAS2(SMat A) { int ibeta, it, irnd, machep, negep, n, steps, nsig, neig; double kappa = 1e-6; double[] las2end = new double[2] { -1.0e-30, 1.0e-30 }; double[] ritz, bnd; double[][] wptr = new double[10][]; svdResetCounters(); int dimensions = A.rows; if (A.cols < dimensions) dimensions = A.cols; int iterations = dimensions; // Check parameters if (check_parameters(A, dimensions, iterations, las2end[0], las2end[1]) > 0) return null; // If A is wide, the SVD is computed on its transpose for speed. bool transpose = false; if (A.cols >= A.rows * 1.2) { //Console.WriteLine("TRANSPOSING THE MATRIX FOR SPEED\n"); transpose = true; A = svdTransposeS(A); } n = A.cols; // Compute machine precision ibeta = it = irnd = machep = negep = 0; machar(ref ibeta, ref it, ref irnd, ref machep, ref negep); eps1 = eps * Math.Sqrt((double)n); reps = Math.Sqrt(eps); eps34 = reps * Math.Sqrt(reps); //Console.WriteLine("Machine precision {0} {1} {2} {3} {4}", ibeta, it, irnd, machep, negep); // Allocate temporary space. wptr[0] = new double[n]; for (int i = 0; i < n; ++i) wptr[0][i] = 0.0; wptr[1] = new double[n]; wptr[2] = new double[n]; wptr[3] = new double[n]; wptr[4] = new double[n]; wptr[5] = new double[n]; wptr[6] = new double[iterations]; wptr[7] = new double[iterations]; wptr[8] = new double[iterations]; wptr[9] = new double[iterations + 1]; ritz = new double[iterations + 1]; for (int i = 0; i < iterations + 1; ++i) ritz[0] = 0.0; bnd = new double[iterations + 1]; for (int i = 0; i < iterations + 1; ++i) bnd[0] = 0.0; LanStore = new double[iterations + MAXLL][]; for (int i = 0; i < iterations + MAXLL; ++i) { LanStore[i] = null; } OPBTemp = new double[A.rows]; // Actually run the lanczos thing: neig = 0; steps = lanso(A, iterations, dimensions, las2end[0], las2end[1], ritz, bnd, wptr, ref neig, n); //Console.WriteLine("NUMBER OF LANCZOS STEPS {0}", steps + 1); //Console.WriteLine("RITZ VALUES STABILIZED = RANK {0}", neig); kappa = svd_dmax(Math.Abs(kappa), eps34); SVDRec R = new SVDRec(); R.d = dimensions; DMat Tmp1 = new DMat(); Tmp1.rows = R.d; Tmp1.cols = A.rows; Tmp1.value = new double[Tmp1.rows][]; for (int mm = 0; mm < Tmp1.rows; ++mm) { Tmp1.value[mm] = new double[Tmp1.cols]; for (int j = 0; j < Tmp1.cols; ++j) { Tmp1.value[mm][j] = 0.0; } } R.Ut = Tmp1; R.S = new double[R.d]; for (int k = 0; k < R.d; ++k) { R.S[k] = 0.0; } DMat Tmp2 = new DMat(); Tmp2.rows = R.d; Tmp2.cols = A.cols; Tmp2.value = new double[Tmp2.rows][]; for (int mm = 0; mm < Tmp2.rows; ++mm) { Tmp2.value[mm] = new double[Tmp2.cols]; for (int j = 0; j < Tmp2.cols; ++j) { Tmp2.value[mm][j] = 0.0; } } R.Vt = Tmp2; nsig = ritvec(n, A, R, kappa, ritz, bnd, wptr[6], wptr[9], wptr[5], steps, neig); // This swaps and transposes the singular matrices if A was transposed. if (transpose) { DMat T; T = R.Ut; R.Ut = R.Vt; R.Vt = T; } return R; }
private static void svdWriteDenseMatrix(DMat D, string filename) { using (FileStream stream = new FileStream(filename, FileMode.Create)) { using (BinaryWriter writer = new BinaryWriter(stream)) { writer.Write(System.Net.IPAddress.HostToNetworkOrder(D.rows)); writer.Write(System.Net.IPAddress.HostToNetworkOrder(D.cols)); for (int k = 0; k < D.rows; ++k) { for (int j = 0; j < D.cols; ++j) { float buf = (float)(D.value[k][j]); byte[] b = BitConverter.GetBytes(buf); int x = BitConverter.ToInt32(b, 0); writer.Write(System.Net.IPAddress.HostToNetworkOrder(x)); } } writer.Flush(); writer.Close(); } stream.Close(); } }