public void TestRandomRegularA() { RandomHelper.Random = new Random(1); for (int i = 0; i < 100; i++) { VectorF column1 = new VectorF(3); RandomHelper.Random.NextVectorF(column1, 1, 2); VectorF column2 = new VectorF(3); RandomHelper.Random.NextVectorF(column2, 1, 2); // Make linearly independent. if (column1 / column1[0] == column2 / column2[0]) { column2[0]++; } // Create linearly independent third column. VectorF column3 = column1 + column2; column3[1]++; // Create A. MatrixF a = new MatrixF(3, 3); a.SetColumn(0, column1); a.SetColumn(1, column2); a.SetColumn(2, column3); SingularValueDecompositionF svd = new SingularValueDecompositionF(a); Assert.AreEqual(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); float condNumber = svd.ConditionNumber; } }
public void TestMatricesWithFullRank() { MatrixF a = new MatrixF(new float[, ] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, -9 } }); SingularValueDecompositionF svd = new SingularValueDecompositionF(a); Assert.AreEqual(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); float condNumber = svd.ConditionNumber; svd = new SingularValueDecompositionF(a.Transposed); Assert.AreEqual(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); condNumber = svd.ConditionNumber; a = new MatrixF(new float[, ] { { 1, 2 }, { 4, 5 }, { 4, 5 } }); svd = new SingularValueDecompositionF(a); Assert.AreEqual(2, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); condNumber = svd.ConditionNumber; }
static Line fitting(Point[] points) { if (points.Length == 2) { return(Line.FromPoints(points[0], points[1])); } float[,] A = new float[points.Length, 3]; for (int i = 0; i < points.Length; i++) { A[i, 0] = points[i].X; A[i, 1] = points[i].Y; A[i, 2] = 1; } SingularValueDecompositionF svd = new SingularValueDecompositionF(A, computeLeftSingularVectors: false, computeRightSingularVectors: true, autoTranspose: true, inPlace: true); float[,] v = svd.RightSingularVectors; float slope = v[2, 1]; float intercept = v[2, 0]; float norm = (float)Math.Sqrt(slope * slope + intercept * intercept); return(Line.FromSlopeIntercept(slope / norm, intercept / norm)); }
public void TestMatricesWithoutFullRank() { MatrixF a = new MatrixF(3, 3); SingularValueDecompositionF svd = new SingularValueDecompositionF(a); Assert.AreEqual(0, svd.NumericalRank); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); float condNumber = svd.ConditionNumber; a = new MatrixF(new float[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 4, 5, 6 } }); svd = new SingularValueDecompositionF(a); Assert.AreEqual(2, svd.NumericalRank); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); svd = new SingularValueDecompositionF(a.Transposed); Assert.AreEqual(2, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, svd.U * svd.S * svd.V.Transposed)); Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, svd.U * svd.S * svd.V.Transposed)); // Repeat to test with cached values. Assert.AreEqual(svd.SingularValues[0], svd.Norm2); condNumber = svd.ConditionNumber; a = new MatrixF(new float[,] { { 1, 2 }, { 1, 2 }, { 1, 2 } }); svd = new SingularValueDecompositionF(a); Assert.AreEqual(1, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); condNumber = svd.ConditionNumber; }
public void TestMatricesWithoutFullRank() { MatrixF a = new MatrixF(3, 3); SingularValueDecompositionF svd = new SingularValueDecompositionF(a); Assert.AreEqual(0, svd.NumericalRank); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); float condNumber = svd.ConditionNumber; a = new MatrixF(new float[, ] { { 1, 2, 3 }, { 4, 5, 6 }, { 4, 5, 6 } }); svd = new SingularValueDecompositionF(a); Assert.AreEqual(2, svd.NumericalRank); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); svd = new SingularValueDecompositionF(a.Transposed); Assert.AreEqual(2, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, svd.U * svd.S * svd.V.Transposed)); Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, svd.U * svd.S * svd.V.Transposed)); // Repeat to test with cached values. Assert.AreEqual(svd.SingularValues[0], svd.Norm2); condNumber = svd.ConditionNumber; a = new MatrixF(new float[, ] { { 1, 2 }, { 1, 2 }, { 1, 2 } }); svd = new SingularValueDecompositionF(a); Assert.AreEqual(1, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); condNumber = svd.ConditionNumber; }
public void TestRandomRectangularA() { RandomHelper.Random = new Random(1); // Every transpose(A) * A is SPD if A has full column rank and m>n. for (int i = 0; i < 100; i++) { // Create A. MatrixF a = new MatrixF(4, 3); RandomHelper.Random.NextMatrixF(a, 0, 1); // Check for full rank with QRD. QRDecompositionF d = new QRDecompositionF(a); SingularValueDecompositionF svd = new SingularValueDecompositionF(a); if (d.HasNumericallyFullRank) { // Rank should be full. Assert.AreEqual(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); } else { // Not full rank - we dont know much, just see if it runs through Assert.Greater(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); } Assert.AreEqual(svd.SingularValues[0], svd.Norm2); float condNumber = svd.ConditionNumber; } }
public void SVD(out Matrix3 U, out float[] S, out Matrix3 V) { SingularValueDecompositionF Decomp = new SingularValueDecompositionF(ToMultidimArray(), true, true); U = new Matrix3(Decomp.LeftSingularVectors); S = Decomp.Diagonal; V = new Matrix3(Decomp.RightSingularVectors); }
static Plane fitting(Point3[] points) { // Set up constraint equations of the form AB = 0, // where B is a column vector of the plane coefficients // in the form b(1)*X + b(2)*Y +b(3)*Z + b(4) = 0. // // A = [XYZ' ones(npts,1)]; % Build constraint matrix if (points.Length < 3) { return(null); } if (points.Length == 3) { return(Plane.FromPoints(points[0], points[1], points[2])); } float[,] A = new float[points.Length, 4]; for (int i = 0; i < points.Length; i++) { A[i, 0] = points[i].X; A[i, 1] = points[i].Y; A[i, 2] = points[i].Z; A[i, 3] = -1; } SingularValueDecompositionF svd = new SingularValueDecompositionF(A, computeLeftSingularVectors: false, computeRightSingularVectors: true, autoTranspose: true, inPlace: true); float[,] v = svd.RightSingularVectors; float a = v[0, 3]; float b = v[1, 3]; float c = v[2, 3]; float d = v[3, 3]; float norm = (float)Math.Sqrt(a * a + b * b + c * c); a /= norm; b /= norm; c /= norm; d /= norm; return(new Plane(a, b, c, -d)); }
public void TestMatricesWithFullRank() { MatrixF a = new MatrixF(new float[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, -9 } }); SingularValueDecompositionF svd = new SingularValueDecompositionF(a); Assert.AreEqual(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); float condNumber = svd.ConditionNumber; svd = new SingularValueDecompositionF(a.Transposed); Assert.AreEqual(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a.Transposed, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); condNumber = svd.ConditionNumber; a = new MatrixF(new float[,] { { 1, 2 }, { 4, 5 }, { 4, 5 } }); svd = new SingularValueDecompositionF(a); Assert.AreEqual(2, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); condNumber = svd.ConditionNumber; }
//SVD and more private static void Task6() { var phrase = TypePhrase(); var termsWeightsMap = new SortedDictionary <string, List <int> >(); var docsRefs = new List <string>(); // Step 1 var A = CreateMatrixA(out termsWeightsMap, out docsRefs); var queryVec = CreateQueryVector(phrase, termsWeightsMap); // Step 2 SingularValueDecompositionF svd = new SingularValueDecompositionF(A); var U = svd.LeftSingularVectors; var S = svd.DiagonalMatrix; var V = svd.RightSingularVectors; var Vt = V.Transpose(); // Step 3 var newRank = 7; var U_rank = U.Get(0, U.GetLength(0), 0, newRank); var S_rank = S.Get(0, newRank, 0, newRank); var V_rank = V.Get(0, V.GetLength(0), 0, newRank); var Vt_rank = V_rank.Transpose(); // Step 4 float[][] docsVectors = GetNewDocVecCoordinates(V_rank); // Step 5 var newQueryVec = GetNewQueryVector(queryVec, U_rank, S_rank); // Step 6 var scores = CalculateSimForDocs(newQueryVec, docsVectors, docsRefs); foreach (var score in scores) { Console.WriteLine("Score for " + score.Key + " = " + score.Value); } }
public void TestWithNaNValues() { MatrixF a = new MatrixF(new[, ] { { 0, float.NaN, 2 }, { 1, 4, 3 }, { 2, 3, 5 } }); var d = new SingularValueDecompositionF(a); foreach (var element in d.SingularValues.ToList()) { Assert.IsNaN(element); } foreach (var element in d.U.ToList(MatrixOrder.RowMajor)) { Assert.IsNaN(element); } foreach (var element in d.V.ToList(MatrixOrder.RowMajor)) { Assert.IsNaN(element); } d = new SingularValueDecompositionF(new MatrixF(4, 3, float.NaN)); foreach (var element in d.SingularValues.ToList()) { Assert.IsNaN(element); } foreach (var element in d.U.ToList(MatrixOrder.RowMajor)) { Assert.IsNaN(element); } foreach (var element in d.V.ToList(MatrixOrder.RowMajor)) { Assert.IsNaN(element); } }
private static float[,] createFundamentalMatrix(float[,] A) { float[,] U, V; float[] D; SingularValueDecompositionF svd = new SingularValueDecompositionF(A, computeLeftSingularVectors: false, computeRightSingularVectors: true, autoTranspose: true, inPlace: true); V = svd.RightSingularVectors; int s = svd.RightSingularVectors.GetLength(1) - 1; float[,] F = { { V[0, s], V[1, s], V[2, s] }, { V[3, s], V[4, s], V[5, s] }, { V[6, s], V[7, s], V[8, s] }, }; svd = new SingularValueDecompositionF(F, computeLeftSingularVectors: true, computeRightSingularVectors: true, autoTranspose: true, inPlace: false); U = svd.LeftSingularVectors; D = svd.Diagonal; V = svd.RightSingularVectors; D[2] = 0; // Reconstruct with rank 2 approximation var newF = U.MultiplyByDiagonal(D).Multiply(V.Transpose()); F = newF; return F; }
/// <summary> /// Creates the fundamental matrix between two /// images from a set of points from each image. /// </summary> /// public static float[,] Fundamental(PointH[] points1, PointH[] points2, out PointH[] epipoles) { var F = Fundamental(points1, points2); SingularValueDecompositionF svd = new SingularValueDecompositionF(F, computeLeftSingularVectors: true, computeRightSingularVectors: true, autoTranspose: true, inPlace: false); var U = svd.LeftSingularVectors; var V = svd.RightSingularVectors; PointH e1 = new PointH(V[0, 2] / V[2, 2], V[1, 2] / V[2, 2], 1); PointH e2 = new PointH(U[0, 2] / U[2, 2], U[1, 2] / U[2, 2], 1); epipoles = new PointH[] { e1, e2 }; return F; }
/// <summary> /// Creates an homography matrix matching points /// from a set of points to another. /// </summary> /// public static MatrixH Homography(PointF[] points1, PointF[] points2) { // Initial argument checks if (points1.Length != points2.Length) throw new ArgumentException("The number of points should be equal."); if (points1.Length < 4) throw new ArgumentException("At least four points are required to fit an homography"); int N = points1.Length; MatrixH T1, T2; // Normalize input points points1 = Tools.Normalize(points1, out T1); points2 = Tools.Normalize(points2, out T2); // Create the matrix A var A = new float[3 * N, 9]; for (int i = 0; i < N; i++) { PointF X = points1[i]; float x = points2[i].X; float y = points2[i].Y; int r = 3 * i; A[r, 0] = 0; A[r, 1] = 0; A[r, 2] = 0; A[r, 3] = -X.X; A[r, 4] = -X.Y; A[r, 5] = -1; A[r, 6] = y * X.X; A[r, 7] = y * X.Y; A[r, 8] = y; r++; A[r, 0] = X.X; A[r, 1] = X.Y; A[r, 2] = 1; A[r, 3] = 0; A[r, 4] = 0; A[r, 5] = 0; A[r, 6] = -x * X.X; A[r, 7] = -x * X.Y; A[r, 8] = -x; r++; A[r, 0] = -y * X.X; A[r, 1] = -y * X.Y; A[r, 2] = -y; A[r, 3] = x * X.X; A[r, 4] = x * X.Y; A[r, 5] = x; A[r, 6] = 0; A[r, 7] = 0; A[r, 8] = 0; } // Create the singular value decomposition SingularValueDecompositionF svd = new SingularValueDecompositionF(A, computeLeftSingularVectors: false, computeRightSingularVectors: true, autoTranspose: false, inPlace: true); float[,] V = svd.RightSingularVectors; // Extract the homography matrix MatrixH H = new MatrixH(V[0, 8], V[1, 8], V[2, 8], V[3, 8], V[4, 8], V[5, 8], V[6, 8], V[7, 8], V[8, 8]); // Denormalize H = T2.Inverse().Multiply(H.Multiply(T1)); return H; }
public void TestRandomRegularA() { RandomHelper.Random = new Random(1); for (int i = 0; i < 100; i++) { VectorF column1 = new VectorF(3); RandomHelper.Random.NextVectorF(column1, 1, 2); VectorF column2 = new VectorF(3); RandomHelper.Random.NextVectorF(column2, 1, 2); // Make linearly independent. if (column1 / column1[0] == column2 / column2[0]) column2[0]++; // Create linearly independent third column. VectorF column3 = column1 + column2; column3[1]++; // Create A. MatrixF a = new MatrixF(3, 3); a.SetColumn(0, column1); a.SetColumn(1, column2); a.SetColumn(2, column3); SingularValueDecompositionF svd = new SingularValueDecompositionF(a); Assert.AreEqual(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); float condNumber = svd.ConditionNumber; } }
public void TestWithNaNValues() { MatrixF a = new MatrixF(new[,] {{ 0, float.NaN, 2 }, { 1, 4, 3 }, { 2, 3, 5}}); var d = new SingularValueDecompositionF(a); foreach (var element in d.SingularValues.ToList()) Assert.IsNaN(element); foreach (var element in d.U.ToList(MatrixOrder.RowMajor)) Assert.IsNaN(element); foreach (var element in d.V.ToList(MatrixOrder.RowMajor)) Assert.IsNaN(element); d = new SingularValueDecompositionF(new MatrixF(4, 3, float.NaN)); foreach (var element in d.SingularValues.ToList()) Assert.IsNaN(element); foreach (var element in d.U.ToList(MatrixOrder.RowMajor)) Assert.IsNaN(element); foreach (var element in d.V.ToList(MatrixOrder.RowMajor)) Assert.IsNaN(element); }
public void TestRandomRectangularA() { RandomHelper.Random = new Random(1); // Every transpose(A) * A is SPD if A has full column rank and m>n. for (int i = 0; i < 100; i++) { // Create A. MatrixF a = new MatrixF(4, 3); RandomHelper.Random.NextMatrixF(a, 0, 1); // Check for full rank with QRD. QRDecompositionF d = new QRDecompositionF(a); SingularValueDecompositionF svd = new SingularValueDecompositionF(a); if (d.HasNumericallyFullRank) { // Rank should be full. Assert.AreEqual(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); } else { // Not full rank - we dont know much, just see if it runs through Assert.Greater(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); } Assert.AreEqual(svd.SingularValues[0], svd.Norm2); float condNumber = svd.ConditionNumber; } }
static Line fitting(Point[] points) { if (points.Length == 2) return Line.FromPoints(points[0], points[1]); float[,] A = new float[points.Length, 3]; for (int i = 0; i < points.Length; i++) { A[i, 0] = points[i].X; A[i, 1] = points[i].Y; A[i, 2] = 1; } SingularValueDecompositionF svd = new SingularValueDecompositionF(A, computeLeftSingularVectors: false, computeRightSingularVectors: true, autoTranspose: true, inPlace: true); float[,] v = svd.RightSingularVectors; float slope = v[2, 1]; float intercept = v[2, 0]; float norm = (float)Math.Sqrt(slope * slope + intercept * intercept); return Line.FromSlopeIntercept(slope / norm, intercept / norm); }
static Plane fitting(Point3[] points) { // Set up constraint equations of the form AB = 0, // where B is a column vector of the plane coefficients // in the form b(1)*X + b(2)*Y +b(3)*Z + b(4) = 0. // // A = [XYZ' ones(npts,1)]; % Build constraint matrix if (points.Length < 3) return null; if (points.Length == 3) return Plane.FromPoints(points[0], points[1], points[2]); float[,] A = new float[points.Length, 4]; for (int i = 0; i < points.Length; i++) { A[i, 0] = points[i].X; A[i, 1] = points[i].Y; A[i, 2] = points[i].Z; A[i, 3] = -1; } SingularValueDecompositionF svd = new SingularValueDecompositionF(A, computeLeftSingularVectors: false, computeRightSingularVectors: true, autoTranspose: true, inPlace: true); float[,] v = svd.RightSingularVectors; float a = v[0, 3]; float b = v[1, 3]; float c = v[2, 3]; float d = v[3, 3]; float norm = (float)Math.Sqrt(a * a + b * b + c * c); a /= norm; b /= norm; c /= norm; d /= norm; return new Plane(a, b, c, -d); }