new back-substitution functions that can do unit triangular solves

release/4.3a0
Frank Dellaert 2009-12-29 13:59:34 +00:00
parent 75ab62a729
commit c43cd425ab
4 changed files with 72 additions and 54 deletions

View File

@ -101,7 +101,7 @@ Vector GaussianConditional::solve(const VectorConfig& x) const {
const Matrix& Aj = it->second; const Matrix& Aj = it->second;
rhs -= Aj * x[j]; rhs -= Aj * x[j];
} }
Vector result = backsubstitution(R_, rhs); Vector result = backSubstituteUpper(R_, rhs, true);
return result; return result;
} }

View File

@ -405,33 +405,43 @@ void householder(Matrix &A, size_t k) {
} }
/* ************************************************************************* */ /* ************************************************************************* */
Vector backsubstitution(const Matrix& R, const Vector& b) Vector backSubstituteUpper(const Matrix& U, const Vector& b, bool unit) {
{ size_t m = U.size1(), n = U.size2();
// result vector #ifndef NDEBUG
Vector result(b.size()); if (m!=n)
throw invalid_argument("backSubstituteUpper: U must be square");
#endif
double tmp = 0.0; Vector result(n);
double div = 0.0; for (size_t i = n; i > 0; i--) {
double tmp = b(i-1);
for (size_t j = i+1; j <= n; j++)
tmp -= U(i-1,j-1) * result(j-1);
if (!unit) tmp /= U(i-1,i-1);
result(i-1) = tmp;
}
int m = R.size1(), n = R.size2(), cols=n; return result;
}
// check each row for non zero values /* ************************************************************************* */
for( size_t i = m ; i > 0 ; i--){ Vector backSubstituteLower(const Matrix& L, const Vector& b, bool unit) {
cols--; size_t m = L.size1(), n = L.size2();
int j = n; #ifndef NDEBUG
if (m!=n)
throw invalid_argument("backSubstituteLower: L must be square");
#endif
div = R(i-1, cols); Vector result(n);
for (size_t i = 1; i <= n; i++) {
double tmp = b(i-1);
for (size_t j = 1; j < i; j++)
tmp -= L(i-1,j-1) * result(j-1);
if (!unit) tmp /= L(i-1,i-1);
result(i-1) = tmp;
}
for( int ii = i ; ii < n ; ii++ ){ return result;
j = j - 1;
tmp = tmp + R(i-1,j) * result(j);
}
// assigne the result vector
result(i-1) = (b(i-1) - tmp) / div;
tmp = 0.0;
}
return result;
} }
/* ************************************************************************* */ /* ************************************************************************* */

View File

@ -207,12 +207,24 @@ void householder_(Matrix& A, size_t k);
void householder(Matrix& A, size_t k); void householder(Matrix& A, size_t k);
/** /**
* backsubstitution * backSubstitute U*x=b
* @param R an upper triangular matrix * @param U an upper triangular matrix
* @param b a RHS vector * @param b a RHS vector
* @return the solution of Rx=b * @param unit, set tru if unit triangular
* @return the solution x of U*x=b
* TODO: use boost
*/
Vector backSubstituteUpper(const Matrix& U, const Vector& b, bool unit=false);
/**
* backSubstitute L*x=b
* @param L an lower triangular matrix
* @param b a RHS vector
* @param unit, set tru if unit triangular
* @return the solution x of L*x=b
* TODO: use boost
*/ */
Vector backsubstitution(const Matrix& R, const Vector& b); Vector backSubstituteLower(const Matrix& L, const Vector& d, bool unit=false);
/** /**
* create a matrix by stacking other matrices * create a matrix by stacking other matrices

View File

@ -386,38 +386,34 @@ TEST( matrix, inverse )
CHECK(assert_equal(expected, Ainv, 1e-4)); CHECK(assert_equal(expected, Ainv, 1e-4));
} }
/* ************************************************************************* */
/* unit test for backsubstitution */
/* ************************************************************************* */ /* ************************************************************************* */
TEST( matrix, backsubtitution ) TEST( matrix, backsubtitution )
{ {
// TEST ONE 2x2 matrix // TEST ONE 2x2 matrix U1*x=b1
Vector expectedA(2); Vector expected1 = Vector_(2, 3.6250, -0.75);
expectedA(0) = 3.6250 ; expectedA(1) = -0.75; Matrix U1 = Matrix_(2, 2,
2., 3.,
0., 4.);
Vector b1 = U1*expected1;
CHECK( assert_equal(expected1 , backSubstituteUpper(U1, b1), 0.000001));
// create a 2x2 matrix // TEST TWO 3x3 matrix U2*x=b2
double dataA[] = {2, 3, Vector expected2 = Vector_(3, 5.5, -8.5, 5.);
0, 4 }; Matrix U2 = Matrix_(3, 3,
Matrix A = Matrix_(2,2,dataA); 3., 5., 6.,
Vector Ab(2); Ab(0) = 5; Ab(1) = -3; 0., 2., 3.,
0., 0., 1.);
Vector b2 = U2*expected2;
CHECK( assert_equal(expected2 , backSubstituteUpper(U2, b2), 0.000001));
CHECK( assert_equal(expectedA , backsubstitution(A, Ab), 0.000001)); // TEST THREE Lower triangular 3x3 matrix L3*x=b3
Vector expected3 = Vector_(3, 1., 1., 1.);
// TEST TWO 3x3 matrix Matrix L3 = Matrix_(3, 3,
Vector expectedB(3); 3., 0., 0.,
expectedB(0) = 5.5 ; expectedB(1) = -8.5; expectedB(2) = 5; 5., 2., 0.,
6., 3., 1.);
Vector b3 = L3*expected3;
// create a 3x3 matrix CHECK( assert_equal(expected3 , backSubstituteLower(L3, b3), 0.000001));
double dataB[] = { 3, 5, 6,
0, 2, 3,
0, 0, 1 };
Matrix B = Matrix_(3,3,dataB);
Vector Bb(3);
Bb(0) = 4; Bb(1) = -2; Bb(2) = 5;
CHECK( assert_equal(expectedB , backsubstitution(B, Bb), 0.000001));
} }
/* ************************************************************************* */ /* ************************************************************************* */