public static object SVD(double[,] Data) { DenseMatrix data = new DenseMatrix(Data); int nRows = data.RowCount, nCols = data.ColumnCount; MathNet.Numerics.LinearAlgebra.Double.Factorization.Svd svd = data.Svd(true); Matrix <double> u = svd.U(); // m x m Matrix <double> w = svd.W(); // m x n, diagonal Matrix <double> vt = svd.VT(); // n x n, transpose object[,] ret = new object[Math.Max(nRows, nCols), nRows + 1 + nCols + 1 + nCols]; for (int i = 0; i < ret.GetLength(0); ++i) { for (int j = 0; j < ret.GetLength(1); ++j) { ret[i, j] = ""; } } for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nRows; ++j) { ret[i, j] = u[i, j]; } } for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nCols; ++j) { ret[i, nRows + 1 + j] = w[i, j]; } } for (int i = 0; i < nCols; ++i) { for (int j = 0; j < nCols; ++j) { ret[i, nRows + 1 + nCols + 1 + j] = vt[j, i]; // Re-transpose, so that they're in the expected format. } } return(ret); }
public override void Estimate(List <Point3D> datas) { double sum_x = 0; double sum_y = 0; double sum_z = 0; foreach (Point3D temp in datas) { sum_x += temp.x; sum_y += temp.y; sum_z += temp.z; } sum_x /= datas.Count; sum_y /= datas.Count; sum_z /= datas.Count; DenseMatrix jacobian = new DenseMatrix(datas.Count, 3); foreach (Point3D temp in datas) { Vector <double> gradient = new DenseVector(3); gradient[0] = temp.x - sum_x; gradient[1] = temp.y - sum_y; gradient[2] = temp.z - sum_z; jacobian.SetRow(datas.IndexOf(temp), gradient); } MathNet.Numerics.LinearAlgebra.Double.Factorization.Svd svd = jacobian.Svd(true); // get matrix of left singular vectors with first n columns of U Matrix <double> U1 = svd.U().SubMatrix(0, datas.Count, 0, 3); // get matrix of singular values Matrix <double> S = new DiagonalMatrix(3, 3, svd.S().ToArray()); // get matrix of right singular vectors Matrix <double> V = svd.VT().Transpose(); Vector <double> parameters = new DenseVector(3); parameters = V.Column(2); x = sum_x; y = sum_y; z = sum_z; i = parameters[0]; j = parameters[1]; k = parameters[2]; }