Added weighted Householder transforms that use precisions perform QDR factorization. Functions create a weighted vector pseudoinverse, and then use the pseudoinverse to substitute a solution into system.
parent
626d06905c
commit
37bc303492
|
@ -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<m; ++i)
|
||||||
|
for (int j=0; j<m; ++j)
|
||||||
|
Hw(i,j) -= x(i)*pseudo(j);
|
||||||
|
|
||||||
|
// zero the selected column below the diagonal
|
||||||
|
for (int i=row+1; i<m; ++i)
|
||||||
|
A(i,row) = 0.0;
|
||||||
|
|
||||||
|
// update As
|
||||||
|
//FIXME: this uselessly updates the top rows as well, and should be fixed
|
||||||
|
Matrix As = sub(A,0,m,row+1,n);
|
||||||
|
Matrix As_new = Hw*As;
|
||||||
|
|
||||||
|
// copy in updated As
|
||||||
|
for (int i=1; i<m; ++i) //index through rows of A
|
||||||
|
for (int j=0; j<As_new.size2(); ++j) //index through columns of As_new
|
||||||
|
A(i,j+row+1) = As_new(i,j);
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
/** Imperative version of Householder QR factorization, Golub & Van Loan p 224
|
/** Imperative version of Householder QR factorization, Golub & Van Loan p 224
|
||||||
* version with Householder vectors below diagonal, as in GVL
|
* version with Householder vectors below diagonal, as in GVL
|
||||||
|
|
10
cpp/Matrix.h
10
cpp/Matrix.h
|
@ -137,6 +137,16 @@ std::pair<Matrix,Matrix> qr(const Matrix& A);
|
||||||
*/
|
*/
|
||||||
void householder_update(Matrix &A, int j, double beta, const Vector& vjm);
|
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
|
* Householder tranformation, Householder vectors below diagonal
|
||||||
* @param k number of columns to zero out below diagonal
|
* @param k number of columns to zero out below diagonal
|
||||||
|
|
|
@ -91,6 +91,12 @@ namespace gtsam {
|
||||||
return v;
|
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) {
|
void print(const Vector& v, const string& s) {
|
||||||
size_t n = v.size();
|
size_t n = v.size();
|
||||||
|
@ -178,6 +184,24 @@ namespace gtsam {
|
||||||
return make_pair(beta, v);
|
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<D.size();i++)
|
||||||
|
D(i)=sqrt(precisions[i]);
|
||||||
|
double normV = 0;
|
||||||
|
for(int i = 0; i<v.size(); i++)
|
||||||
|
normV += v[i]*v[i]*D[i];
|
||||||
|
Vector sol(v.size());
|
||||||
|
for(int i = 0; i<v.size(); i++)
|
||||||
|
sol[i] = D[i]*v[i];
|
||||||
|
return sol/normV;
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
Vector concatVectors(size_t nrVectors, ...)
|
Vector concatVectors(size_t nrVectors, ...)
|
||||||
{
|
{
|
||||||
|
|
15
cpp/Vector.h
15
cpp/Vector.h
|
@ -40,6 +40,12 @@ Vector Vector_(size_t m, ...);
|
||||||
*/
|
*/
|
||||||
Vector zero(size_t n);
|
Vector zero(size_t n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create vector initialized to ones
|
||||||
|
* @ param size
|
||||||
|
*/
|
||||||
|
Vector ones(size_t n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if all zero
|
* check if all zero
|
||||||
*/
|
*/
|
||||||
|
@ -97,6 +103,15 @@ Vector sub(const Vector &v, size_t i1, size_t i2);
|
||||||
*/
|
*/
|
||||||
std::pair<double,Vector> house(Vector &x);
|
std::pair<double,Vector> 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
|
* concatenate Vectors
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -438,7 +438,6 @@ TEST( matrix, row_major_access )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
||||||
TEST( matrix, svd )
|
TEST( matrix, svd )
|
||||||
{
|
{
|
||||||
double data[] = {2,1,0};
|
double data[] = {2,1,0};
|
||||||
|
@ -452,6 +451,38 @@ TEST( matrix, svd )
|
||||||
EQUALITY(S,S1);
|
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); }
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
||||||
|
|
|
@ -126,6 +126,28 @@ TEST( TestVector, concatVectors)
|
||||||
CHECK(AB == C);
|
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); }
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
|
|
Loading…
Reference in New Issue