diff --git a/cpp/Matrix.cpp b/cpp/Matrix.cpp index 03eff4272..8c31f9c18 100644 --- a/cpp/Matrix.cpp +++ b/cpp/Matrix.cpp @@ -269,6 +269,32 @@ void householder_update(Matrix &A, int j, double beta, const Vector& vjm) { } } +/* ************************************************************************* */ +void whouse_subs(Matrix& A, unsigned int row, const Vector& pseudo, const Vector& x) { + // get sizes + size_t m = A.size1(); size_t n = A.size2(); + + // calculate Hw + Matrix Hw = eye(m,m); + for (int i=0; i qr(const Matrix& A); */ void householder_update(Matrix &A, int j, double beta, const Vector& vjm); +/* + * Imperative version of weighted Householder substitution + * @param A is the matrix to reduce + * @param row is the row to start on (rows above aren't affected) + * @param pseudo is the pseudoinverse of the first column of A + * @param x is the first column of A + * A is updated into non-normalied R of A that has been updated + */ +void whouse_subs(Matrix& A, unsigned int row, const Vector& pseudo, const Vector& x); + /** * Householder tranformation, Householder vectors below diagonal * @param k number of columns to zero out below diagonal diff --git a/cpp/Vector.cpp b/cpp/Vector.cpp index feefbf2f5..96c415203 100644 --- a/cpp/Vector.cpp +++ b/cpp/Vector.cpp @@ -91,6 +91,12 @@ namespace gtsam { return v; } + /* ************************************************************************* */ + Vector ones(size_t n) { + Vector v(n); fill_n(v.begin(),n,1.0); + return v; + } + /* ************************************************************************* */ void print(const Vector& v, const string& s) { size_t n = v.size(); @@ -178,6 +184,24 @@ namespace gtsam { return make_pair(beta, v); } + /* ************************************************************************* */ + Vector whouse_solve(const Vector& v, const Vector& precisions) { + if (v.size() != precisions.size()) + throw invalid_argument("V and precisions have different sizes!"); + // get the square root of the precisions + //FIXME: this probably means that storing precisions is a bad idea + Vector D(precisions.size()); + for(int i=0;i house(Vector &x); +/** + * Weighted Householder solution vector, + * a.k.a., the pseudoinverse of the column + * @param v is the first column of the matrix to solve + * @param precisions is a vector of precisions ( sigma^(-2) ) + * @return the pseudoinverse of v + */ +Vector whouse_solve(const Vector& v, const Vector& precisions); + /** * concatenate Vectors */ diff --git a/cpp/testMatrix.cpp b/cpp/testMatrix.cpp index 82c085e86..93be74c08 100644 --- a/cpp/testMatrix.cpp +++ b/cpp/testMatrix.cpp @@ -438,7 +438,6 @@ TEST( matrix, row_major_access ) } /* ************************************************************************* */ - TEST( matrix, svd ) { double data[] = {2,1,0}; @@ -452,6 +451,38 @@ TEST( matrix, svd ) EQUALITY(S,S1); } +/* ************************************************************************* */ +TEST( matrix, whouse_subs ) +{ + // create the system + Matrix A(2,2); + A(0,0) = 1; A(0,1) = 3; + A(1,0) = 2; A(1,1) = 4; + + // Vector to eliminate + Vector x(2); + x(0) = 1.0; x(1) = 2.0; + + Vector tau(2); //correspond to sigmas = [0.1 0.2] + tau(0) = 100; tau(1) = 25; + + // find the pseudoinverse + Vector pseudo = whouse_solve(x, tau); + + // substitute + int row = 0; // eliminating the first column + whouse_subs(A, row, pseudo, x); + + // create expected value + Matrix exp(2,2); + exp(0,0) = 1.0; exp(0,1) = 3.0; + exp(1,0) = 0.0; exp(1,1) = -2.0/3.0; + + // verify + CHECK(assert_equal(A, exp)); +} + + /* ************************************************************************* */ int main() { TestResult tr; return TestRegistry::runAllTests(tr); } diff --git a/cpp/testVector.cpp b/cpp/testVector.cpp index 383e80d3b..2274f260d 100644 --- a/cpp/testVector.cpp +++ b/cpp/testVector.cpp @@ -126,6 +126,28 @@ TEST( TestVector, concatVectors) CHECK(AB == C); } +/* ************************************************************************* */ +TEST( TestVector, whouse_solve ) +{ + // column from a matrix + Vector x(2); + x(0) = 1.0; x(1) = 2.0; + + // create precisions - correspond to sigmas = [0.1 0.2] + Vector tau(2); + tau(0) = 100; tau(1) = 25; + + // perform solve + Vector act = whouse_solve(x, tau); + + // construct expected + Vector exp(2); + exp(0) = 1.0/3.0; exp(1) = 1.0/3.0; + + // verify + CHECK(assert_equal(act, exp)); +} + /* ************************************************************************* */ int main() { TestResult tr; return TestRegistry::runAllTests(tr); } /* ************************************************************************* */