There was no unit test for DLT. Guess what, it never survived the switch to Eigen. Fixed now.
parent
1e190f7c90
commit
f15d242a78
|
|
@ -671,31 +671,21 @@ void svd(const Matrix& A, Matrix& U, Vector& S, Matrix& V) {
|
||||||
boost::tuple<int, double, Vector> DLT(const Matrix& A, double rank_tol) {
|
boost::tuple<int, double, Vector> DLT(const Matrix& A, double rank_tol) {
|
||||||
|
|
||||||
// Check size of A
|
// Check size of A
|
||||||
int m = A.rows(), n = A.cols();
|
int n = A.rows(), p = A.cols(), m = min(n,p);
|
||||||
if (m < n) throw invalid_argument(
|
|
||||||
"DLT: m<n, pad A with zero rows if needed.");
|
|
||||||
|
|
||||||
// Do SVD on A
|
// Do SVD on A
|
||||||
Matrix U, V;
|
Eigen::JacobiSVD<Matrix> svd(A, Eigen::ComputeFullV);
|
||||||
Vector S;
|
Vector s = svd.singularValues();
|
||||||
// static const bool sort = false;
|
Matrix V = svd.matrixV();
|
||||||
svd(A, U, S, V); // TODO: is it a problem for this to be sorted?
|
|
||||||
|
|
||||||
// Find rank
|
// Find rank
|
||||||
int rank = 0;
|
int rank = 0;
|
||||||
for (int j = 0; j < n; j++)
|
for (int j = 0; j < m; j++)
|
||||||
if (S(j) > rank_tol) rank++;
|
if (s(j) > rank_tol) rank++;
|
||||||
// Find minimum singular value and corresponding column index
|
|
||||||
int min_j = n - 1;
|
|
||||||
double min_S = S(min_j);
|
|
||||||
for (int j = 0; j < n - 1; j++)
|
|
||||||
if (S(j) < min_S) {
|
|
||||||
min_j = j;
|
|
||||||
min_S = S(j);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return rank, minimum singular value, and corresponding column of V
|
// Return rank, error, and corresponding column of V
|
||||||
return boost::tuple<int, double, Vector>(rank, min_S, Vector(column(V, min_j)));
|
double error = m<p ? 0 : s(m-1);
|
||||||
|
return boost::tuple<int, double, Vector>(rank, error, Vector(column(V, p-1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
||||||
|
|
@ -1052,32 +1052,55 @@ TEST( matrix, svd3 )
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST( matrix, svd4 )
|
TEST( matrix, svd4 )
|
||||||
{
|
{
|
||||||
Matrix U, V;
|
Matrix U, V;
|
||||||
Vector s;
|
Vector s;
|
||||||
|
|
||||||
Matrix A = Matrix_(3,2,
|
Matrix A = Matrix_(3,2,
|
||||||
0.8147, 0.9134,
|
0.8147, 0.9134,
|
||||||
0.9058, 0.6324,
|
0.9058, 0.6324,
|
||||||
0.1270, 0.0975);
|
0.1270, 0.0975);
|
||||||
|
|
||||||
Matrix expectedU = Matrix_(3,2,
|
Matrix expectedU = Matrix_(3,2,
|
||||||
0.7397, 0.6724,
|
0.7397, 0.6724,
|
||||||
0.6659, -0.7370,
|
0.6659, -0.7370,
|
||||||
0.0970, -0.0689);
|
0.0970, -0.0689);
|
||||||
|
|
||||||
Vector expected_s = Vector_(2, 1.6455, 0.1910);
|
Vector expected_s = Vector_(2, 1.6455, 0.1910);
|
||||||
|
|
||||||
Matrix expectedV = Matrix_(2,2,
|
Matrix expectedV = Matrix_(2,2,
|
||||||
0.7403, -0.6723,
|
0.7403, -0.6723,
|
||||||
0.6723, 0.7403);
|
0.6723, 0.7403);
|
||||||
|
|
||||||
svd(A, U, s, V);
|
svd(A, U, s, V);
|
||||||
Matrix reconstructed = U * diag(s) * trans(V);
|
Matrix reconstructed = U * diag(s) * trans(V);
|
||||||
|
|
||||||
EXPECT(assert_equal(A, reconstructed, 1e-4));
|
EXPECT(assert_equal(A, reconstructed, 1e-4));
|
||||||
EXPECT(assert_equal(expectedU,U, 1e-3));
|
EXPECT(assert_equal(expectedU,U, 1e-3));
|
||||||
EXPECT(assert_equal(expected_s,s, 1e-4));
|
EXPECT(assert_equal(expected_s,s, 1e-4));
|
||||||
EXPECT(assert_equal(expectedV,V, 1e-4));
|
EXPECT(assert_equal(expectedV,V, 1e-4));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST( matrix, DLT )
|
||||||
|
{
|
||||||
|
Matrix A = Matrix_(8,9,
|
||||||
|
0.21, -0.42, -10.71, 0.18, -0.36, -9.18, -0.61, 1.22, 31.11,
|
||||||
|
0.44, -0.66, -15.84, 0.34, -0.51, -12.24, -1.64, 2.46, 59.04,
|
||||||
|
0.69, -8.28, -12.19, -0.48, 5.76, 8.48, -1.89, 22.68, 33.39,
|
||||||
|
0.96, -8.4, -17.76, -0.6, 5.25, 11.1, -3.36, 29.4, 62.16,
|
||||||
|
1.25, 0.3, 2.75, -3.5, -0.84, -7.7, 16.25, 3.9, 35.75,
|
||||||
|
1.56, 0.42, 4.56, -3.38, -0.91, -9.88, 22.36, 6.02, 65.36,
|
||||||
|
1.89, 2.24, 3.99, 3.24, 3.84, 6.84, 18.09, 21.44, 38.19,
|
||||||
|
2.24, 2.48, 6.24, 3.08, 3.41, 8.58, 24.64, 27.28, 68.64
|
||||||
|
);
|
||||||
|
int rank;
|
||||||
|
double error;
|
||||||
|
Vector actual;
|
||||||
|
boost::tie(rank,error,actual) = DLT(A);
|
||||||
|
Vector expected = Vector_(9, -0.0, 0.2357, 0.4714, -0.2357, 0.0, - 0.4714,-0.4714, 0.4714, 0.0);
|
||||||
|
EXPECT_LONGS_EQUAL(8,rank);
|
||||||
|
EXPECT_DOUBLES_EQUAL(0,error,1e-8);
|
||||||
|
EXPECT(assert_equal(expected, actual, 1e-4));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue