Refactoring of weightedPseudoInverse, emul, sum

release/4.3a0
Frank Dellaert 2009-11-13 06:14:55 +00:00
parent 2178589263
commit 17aaae42d8
2 changed files with 50 additions and 26 deletions

View File

@ -6,6 +6,7 @@
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <limits>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
@ -40,21 +41,10 @@ namespace gtsam {
#endif #endif
va_end(args); va_end(args);
/*
p += (n < 0) ? sizeof buf - 3 : n;
while ( p > buf && isspace(p[-1]) )
*--p = '\0';
*p++ = '\r';
*p++ = '\n';
*p = '\0';
*/
#ifdef WIN32 #ifdef WIN32
OutputDebugString(buf); OutputDebugString(buf);
#else #else
printf(buf); printf("%s",buf);
#endif #endif
} }
@ -153,6 +143,16 @@ namespace gtsam {
return v_return; return v_return;
} }
/* ************************************************************************* */
Vector emul(const Vector &a, const Vector &b) {
size_t n = a.size();
assert (b.size()==n);
Vector c(n);
for( size_t i = 0; i < n; i++ )
c(i) = a(i)*b(i);
return c;
}
/* ************************************************************************* */ /* ************************************************************************* */
Vector ediv(const Vector &a, const Vector &b) { Vector ediv(const Vector &a, const Vector &b) {
size_t n = a.size(); size_t n = a.size();
@ -163,6 +163,15 @@ namespace gtsam {
return c; return c;
} }
/* ************************************************************************* */
double sum(const Vector &a) {
double result;
size_t n = a.size();
for( size_t i = 0; i < n; i++ )
result += a(i);
return result;
}
/* ************************************************************************* */ /* ************************************************************************* */
pair<double, Vector > house(Vector &x) pair<double, Vector > house(Vector &x)
{ {
@ -195,27 +204,27 @@ namespace gtsam {
if (a.size() != m) if (a.size() != m)
throw invalid_argument("V and precisions have different sizes!"); throw invalid_argument("V and precisions have different sizes!");
// detect constraints and sanity-check // If there is a valid (a!=0) constraint (sigma==0) return the first one
for(int i=0; i<m; ++i) for(int i=0; i<m; ++i)
if (sigmas[i] < 1e-9 && fabs(a[i]) > 1e-9) if (sigmas[i] < 1e-9 && fabs(a[i]) > 1e-9)
return make_pair(delta(m,i,1/a[i]), 1.0/0.0); return make_pair(delta(m,i,1/a[i]), std::numeric_limits<double>::infinity());
// normal case // Form psuedo-inverse inv(a'inv(Sigma)a)a'inv(Sigma)
double normV = 0.; // For diagonal Sigma, inv(Sigma) = diag(precisions)
double precision = 0;
Vector precisions(m); Vector precisions(m);
for(int i = 0; i<a.size(); i++) { for(int i = 0; i<m; i++) {
if (sigmas[i] < 1e-5) { if (fabs(a[i]) < 1e-9) // also catches remaining sigma==0 rows
precisions[i] = 1./0.; precisions[i] = 0.;
} else { else {
precisions[i] = 1./(sigmas[i]*sigmas[i]); precisions[i] = 1./(sigmas[i]*sigmas[i]);
normV += a[i]*a[i]*precisions[i]; precision += a[i]*a[i]*precisions[i];
} }
} }
Vector sol = zero(a.size()); // precision = a'inv(Sigma)a
for(int i = 0; i<a.size(); i++) if (precision<1e-9) return make_pair(zero(m), precision);
if (sigmas[i] > 1e-5) Vector pseudo = emul(precisions,a);
sol[i] = precisions[i]*a[i]; return make_pair(pseudo/precision, precision);
return make_pair(sol/normV, normV);
} }
/* ************************************************************************* */ /* ************************************************************************* */

View File

@ -110,6 +110,14 @@ bool assert_equal(const Vector& vec1, const Vector& vec2, double tol=1e-9);
*/ */
Vector sub(const Vector &v, size_t i1, size_t i2); Vector sub(const Vector &v, size_t i1, size_t i2);
/**
* elementwise multiplication
* @param a first vector
* @param b second vector
* @return vector [a(i)*b(i)]
*/
Vector emul(const Vector &a, const Vector &b);
/** /**
* elementwise division * elementwise division
* @param a first vector * @param a first vector
@ -118,6 +126,13 @@ Vector sub(const Vector &v, size_t i1, size_t i2);
*/ */
Vector ediv(const Vector &a, const Vector &b); Vector ediv(const Vector &a, const Vector &b);
/**
* sum vector elements
* @param a vector
* @return sum_i a(i)
*/
double sum(const Vector &a);
/** /**
* house(x,j) computes HouseHolder vector v and scaling factor beta * house(x,j) computes HouseHolder vector v and scaling factor beta
* from x, such that the corresponding Householder reflection zeroes out * from x, such that the corresponding Householder reflection zeroes out