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