Define Errors as a typedef to FastList<Vector>.

release/4.3a0
Frank Dellaert 2023-01-09 20:09:50 -08:00
parent 36d6b70667
commit 3b369e5d8e
3 changed files with 56 additions and 70 deletions

View File

@ -26,16 +26,18 @@ using namespace std;
namespace gtsam { namespace gtsam {
/* ************************************************************************* */ /* ************************************************************************* */
Errors::Errors(const VectorValues& V) { Errors createErrors(const VectorValues& V) {
Errors result;
for (const Vector& e : V | boost::adaptors::map_values) { for (const Vector& e : V | boost::adaptors::map_values) {
push_back(e); result.push_back(e);
} }
return result;
} }
/* ************************************************************************* */ /* ************************************************************************* */
void Errors::print(const std::string& s) const { void print(const Errors& e, const string& s) {
cout << s << endl; cout << s << endl;
for(const Vector& v: *this) for(const Vector& v: e)
gtsam::print(v); gtsam::print(v);
} }
@ -48,50 +50,49 @@ struct equalsVector : public std::function<bool(const Vector&, const Vector&)> {
} }
}; };
bool Errors::equals(const Errors& expected, double tol) const { bool equality(const Errors& actual, const Errors& expected, double tol) {
if( size() != expected.size() ) return false; if (actual.size() != expected.size()) return false;
return equal(begin(),end(),expected.begin(),equalsVector(tol)); return equal(actual.begin(), actual.end(), expected.begin(),
equalsVector(tol));
} }
/* ************************************************************************* */ /* ************************************************************************* */
Errors Errors::operator+(const Errors& b) const { Errors operator+(const Errors& a, const Errors& b) {
#ifndef NDEBUG #ifndef NDEBUG
size_t m = size(); size_t m = a.size();
if (b.size()!=m) if (b.size()!=m)
throw(std::invalid_argument("Errors::operator+: incompatible sizes")); throw(std::invalid_argument("Errors::operator+: incompatible sizes"));
#endif #endif
Errors result; Errors result;
Errors::const_iterator it = b.begin(); Errors::const_iterator it = b.begin();
for(const Vector& ai: *this) for(const Vector& ai: a)
result.push_back(ai + *(it++)); result.push_back(ai + *(it++));
return result; return result;
} }
/* ************************************************************************* */ /* ************************************************************************* */
Errors Errors::operator-(const Errors& b) const { Errors operator-(const Errors& a, const Errors& b) {
#ifndef NDEBUG #ifndef NDEBUG
size_t m = size(); size_t m = a.size();
if (b.size()!=m) if (b.size()!=m)
throw(std::invalid_argument("Errors::operator-: incompatible sizes")); throw(std::invalid_argument("Errors::operator-: incompatible sizes"));
#endif #endif
Errors result; Errors result;
Errors::const_iterator it = b.begin(); Errors::const_iterator it = b.begin();
for(const Vector& ai: *this) for(const Vector& ai: a)
result.push_back(ai - *(it++)); result.push_back(ai - *(it++));
return result; return result;
} }
/* ************************************************************************* */ /* ************************************************************************* */
Errors Errors::operator-() const { Errors operator-(const Errors& a) {
Errors result; Errors result;
for(const Vector& ai: *this) for(const Vector& ai: a)
result.push_back(-ai); result.push_back(-ai);
return result; return result;
} }
/* ************************************************************************* */ /* ************************************************************************* */
double dot(const Errors& a, const Errors& b) { double dot(const Errors& a, const Errors& b) {
#ifndef NDEBUG #ifndef NDEBUG
@ -102,7 +103,7 @@ double dot(const Errors& a, const Errors& b) {
double result = 0.0; double result = 0.0;
Errors::const_iterator it = b.begin(); Errors::const_iterator it = b.begin();
for(const Vector& ai: a) for(const Vector& ai: a)
result += gtsam::dot(ai, *(it++)); result += gtsam::dot<Vector,Vector>(ai, *(it++));
return result; return result;
} }
@ -113,11 +114,6 @@ void axpy(double alpha, const Errors& x, Errors& y) {
yi += alpha * (*(it++)); yi += alpha * (*(it++));
} }
/* ************************************************************************* */
void print(const Errors& a, const string& s) {
a.print(s);
}
/* ************************************************************************* */ /* ************************************************************************* */
} // gtsam } // gtsam

View File

@ -20,8 +20,8 @@
#pragma once #pragma once
#include <gtsam/base/FastList.h> #include <gtsam/base/FastList.h>
#include <gtsam/base/Vector.h>
#include <gtsam/base/Testable.h> #include <gtsam/base/Testable.h>
#include <gtsam/base/Vector.h>
#include <string> #include <string>
@ -30,54 +30,44 @@ namespace gtsam {
// Forward declarations // Forward declarations
class VectorValues; class VectorValues;
/** vector of errors */ /// Errors is a vector of errors.
class GTSAM_EXPORT Errors : public FastList<Vector> { using Errors = FastList<Vector>;
using Base = FastList<Vector>; /// Break V into pieces according to its start indices.
GTSAM_EXPORT Errors createErrors(const VectorValues& V);
public: /// Print an Errors instance.
GTSAM_EXPORT void print(const Errors& e, const std::string& s = "Errors");
using Base::Base; // inherit constructors // Check equality for unit testing.
GTSAM_EXPORT bool equality(const Errors& actual, const Errors& expected,
double tol = 1e-9);
/** Default constructor */ /// Addition.
Errors() = default; GTSAM_EXPORT Errors operator+(const Errors& a, const Errors& b);
/** break V into pieces according to its start indices */ /// Subtraction.
Errors(const VectorValues&V); GTSAM_EXPORT Errors operator-(const Errors& a, const Errors& b);
/** print */ /// Negation.
void print(const std::string& s = "Errors") const; GTSAM_EXPORT Errors operator-(const Errors& a);
/** equals, for unit testing */ /// Dot product.
bool equals(const Errors& expected, double tol=1e-9) const;
/** Addition */
Errors operator+(const Errors& b) const;
/** subtraction */
Errors operator-(const Errors& b) const;
/** negation */
Errors operator-() const ;
}; // Errors
/**
* dot product
*/
GTSAM_EXPORT double dot(const Errors& a, const Errors& b); GTSAM_EXPORT double dot(const Errors& a, const Errors& b);
/** /// BLAS level 2 style AXPY, `y := alpha*x + y`
* BLAS level 2 style
*/
GTSAM_EXPORT void axpy(double alpha, const Errors& x, Errors& y); GTSAM_EXPORT void axpy(double alpha, const Errors& x, Errors& y);
/** print with optional string */
GTSAM_EXPORT void print(const Errors& a, const std::string& s = "Error");
/// traits /// traits
template <> template <>
struct traits<Errors> : public Testable<Errors> { struct traits<Errors> {
static void Print(const Errors& e, const std::string& str = "") {
print(e, str);
}
static bool Equals(const Errors& actual, const Errors& expected,
double tol = 1e-8) {
return equality(actual, expected, tol);
}
}; };
} //\ namespace gtsam } // namespace gtsam

View File

@ -110,7 +110,7 @@ VectorValues SubgraphPreconditioner::x(const VectorValues& y) const {
/* ************************************************************************* */ /* ************************************************************************* */
double SubgraphPreconditioner::error(const VectorValues& y) const { double SubgraphPreconditioner::error(const VectorValues& y) const {
Errors e(y); Errors e = createErrors(y);
VectorValues x = this->x(y); VectorValues x = this->x(y);
Errors e2 = Ab2_.gaussianErrors(x); Errors e2 = Ab2_.gaussianErrors(x);
return 0.5 * (dot(e, e) + dot(e2,e2)); return 0.5 * (dot(e, e) + dot(e2,e2));
@ -129,7 +129,7 @@ VectorValues SubgraphPreconditioner::gradient(const VectorValues &y) const {
/* ************************************************************************* */ /* ************************************************************************* */
// Apply operator A, A*y = [I;A2*inv(R1)]*y = [y; A2*inv(R1)*y] // Apply operator A, A*y = [I;A2*inv(R1)]*y = [y; A2*inv(R1)*y]
Errors SubgraphPreconditioner::operator*(const VectorValues &y) const { Errors SubgraphPreconditioner::operator*(const VectorValues &y) const {
Errors e(y); Errors e = createErrors(y);
VectorValues x = Rc1_.backSubstitute(y); /* x=inv(R1)*y */ VectorValues x = Rc1_.backSubstitute(y); /* x=inv(R1)*y */
Errors e2 = Ab2_ * x; /* A2*x */ Errors e2 = Ab2_ * x; /* A2*x */
e.splice(e.end(), e2); e.splice(e.end(), e2);