reorg the nonlinear/linear parameters to accommodate the iterative solvers
parent
9bf1d0e768
commit
ace4327897
|
@ -113,7 +113,7 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
// first using sequential elimination
|
// first using sequential elimination
|
||||||
LevenbergMarquardtParams lmParams;
|
LevenbergMarquardtParams lmParams;
|
||||||
lmParams.elimination = LevenbergMarquardtParams::SEQUENTIAL;
|
lmParams.linearSolverType = LevenbergMarquardtParams::SEQUENTIAL_CHOLESKY;
|
||||||
Values resultSequential = LevenbergMarquardtOptimizer(graph, initial, lmParams).optimize();
|
Values resultSequential = LevenbergMarquardtOptimizer(graph, initial, lmParams).optimize();
|
||||||
resultSequential.print("final result (solved with a sequential solver)");
|
resultSequential.print("final result (solved with a sequential solver)");
|
||||||
|
|
||||||
|
|
|
@ -33,25 +33,25 @@ void DoglegOptimizer::iterate(void) {
|
||||||
const Ordering& ordering = *params_.ordering;
|
const Ordering& ordering = *params_.ordering;
|
||||||
GaussianFactorGraph::shared_ptr linear = graph_.linearize(state_.values, ordering);
|
GaussianFactorGraph::shared_ptr linear = graph_.linearize(state_.values, ordering);
|
||||||
|
|
||||||
// Get elimination method
|
|
||||||
GaussianFactorGraph::Eliminate eliminationMethod = params_.getEliminationFunction();
|
|
||||||
|
|
||||||
// Pull out parameters we'll use
|
// Pull out parameters we'll use
|
||||||
const bool dlVerbose = (params_.verbosityDL > DoglegParams::SILENT);
|
const bool dlVerbose = (params_.verbosityDL > DoglegParams::SILENT);
|
||||||
|
|
||||||
// Do Dogleg iteration with either Multifrontal or Sequential elimination
|
// Do Dogleg iteration with either Multifrontal or Sequential elimination
|
||||||
DoglegOptimizerImpl::IterationResult result;
|
DoglegOptimizerImpl::IterationResult result;
|
||||||
|
|
||||||
if(params_.elimination == DoglegParams::MULTIFRONTAL) {
|
if ( params_.isMultifrontal() ) {
|
||||||
GaussianBayesTree bt;
|
GaussianBayesTree bt;
|
||||||
bt.insert(GaussianJunctionTree(*linear).eliminate(eliminationMethod));
|
bt.insert(GaussianJunctionTree(*linear).eliminate(params_.getEliminationFunction()));
|
||||||
result = DoglegOptimizerImpl::Iterate(state_.Delta, DoglegOptimizerImpl::ONE_STEP_PER_ITERATION, bt, graph_, state_.values, ordering, state_.error, dlVerbose);
|
result = DoglegOptimizerImpl::Iterate(state_.Delta, DoglegOptimizerImpl::ONE_STEP_PER_ITERATION, bt, graph_, state_.values, ordering, state_.error, dlVerbose);
|
||||||
|
}
|
||||||
} else if(params_.elimination == DoglegParams::SEQUENTIAL) {
|
else if ( params_.isSequential() ) {
|
||||||
GaussianBayesNet::shared_ptr bn = EliminationTree<GaussianFactor>::Create(*linear)->eliminate(eliminationMethod);
|
GaussianBayesNet::shared_ptr bn = EliminationTree<GaussianFactor>::Create(*linear)->eliminate(params_.getEliminationFunction());
|
||||||
result = DoglegOptimizerImpl::Iterate(state_.Delta, DoglegOptimizerImpl::ONE_STEP_PER_ITERATION, *bn, graph_, state_.values, ordering, state_.error, dlVerbose);
|
result = DoglegOptimizerImpl::Iterate(state_.Delta, DoglegOptimizerImpl::ONE_STEP_PER_ITERATION, *bn, graph_, state_.values, ordering, state_.error, dlVerbose);
|
||||||
|
}
|
||||||
} else {
|
else if ( params_.isSPCG() ) {
|
||||||
|
throw runtime_error("todo: ");
|
||||||
|
}
|
||||||
|
else {
|
||||||
throw runtime_error("Optimization parameter is invalid: DoglegParams::elimination");
|
throw runtime_error("Optimization parameter is invalid: DoglegParams::elimination");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,13 +35,18 @@ void GaussNewtonOptimizer::iterate() {
|
||||||
// Optimize
|
// Optimize
|
||||||
VectorValues delta;
|
VectorValues delta;
|
||||||
{
|
{
|
||||||
GaussianFactorGraph::Eliminate eliminationMethod = params_.getEliminationFunction();
|
if ( params_.isMultifrontal() ) {
|
||||||
if(params_.elimination == GaussNewtonParams::MULTIFRONTAL)
|
delta = GaussianJunctionTree(*linear).optimize(params_.getEliminationFunction());
|
||||||
delta = GaussianJunctionTree(*linear).optimize(eliminationMethod);
|
}
|
||||||
else if(params_.elimination == GaussNewtonParams::SEQUENTIAL)
|
else if ( params_.isSequential() ) {
|
||||||
delta = gtsam::optimize(*EliminationTree<GaussianFactor>::Create(*linear)->eliminate(eliminationMethod));
|
delta = gtsam::optimize(*EliminationTree<GaussianFactor>::Create(*linear)->eliminate(params_.getEliminationFunction()));
|
||||||
else
|
}
|
||||||
|
else if ( params_.isSPCG() ) {
|
||||||
|
throw runtime_error("todo: ");
|
||||||
|
}
|
||||||
|
else {
|
||||||
throw runtime_error("Optimization parameter is invalid: GaussNewtonParams::elimination");
|
throw runtime_error("Optimization parameter is invalid: GaussNewtonParams::elimination");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe show output
|
// Maybe show output
|
||||||
|
|
|
@ -32,9 +32,6 @@ void LevenbergMarquardtOptimizer::iterate() {
|
||||||
// Linearize graph
|
// Linearize graph
|
||||||
GaussianFactorGraph::shared_ptr linear = graph_.linearize(state_.values, *params_.ordering);
|
GaussianFactorGraph::shared_ptr linear = graph_.linearize(state_.values, *params_.ordering);
|
||||||
|
|
||||||
// Get elimination method
|
|
||||||
GaussianFactorGraph::Eliminate eliminationMethod = params_.getEliminationFunction();
|
|
||||||
|
|
||||||
// Pull out parameters we'll use
|
// Pull out parameters we'll use
|
||||||
const NonlinearOptimizerParams::Verbosity nloVerbosity = params_.verbosity;
|
const NonlinearOptimizerParams::Verbosity nloVerbosity = params_.verbosity;
|
||||||
const LevenbergMarquardtParams::VerbosityLM lmVerbosity = params_.verbosityLM;
|
const LevenbergMarquardtParams::VerbosityLM lmVerbosity = params_.verbosityLM;
|
||||||
|
@ -67,12 +64,18 @@ void LevenbergMarquardtOptimizer::iterate() {
|
||||||
|
|
||||||
// Optimize
|
// Optimize
|
||||||
VectorValues delta;
|
VectorValues delta;
|
||||||
if(params_.elimination == SuccessiveLinearizationParams::MULTIFRONTAL)
|
if ( params_.isMultifrontal() ) {
|
||||||
delta = GaussianJunctionTree(dampedSystem).optimize(eliminationMethod);
|
delta = GaussianJunctionTree(dampedSystem).optimize(params_.getEliminationFunction());
|
||||||
else if(params_.elimination == SuccessiveLinearizationParams::SEQUENTIAL)
|
}
|
||||||
delta = gtsam::optimize(*EliminationTree<GaussianFactor>::Create(dampedSystem)->eliminate(eliminationMethod));
|
else if ( params_.isSequential() ) {
|
||||||
else
|
delta = gtsam::optimize(*EliminationTree<GaussianFactor>::Create(dampedSystem)->eliminate(params_.getEliminationFunction()));
|
||||||
|
}
|
||||||
|
else if ( params_.isSPCG() ) {
|
||||||
|
throw runtime_error("todo: ");
|
||||||
|
}
|
||||||
|
else {
|
||||||
throw runtime_error("Optimization parameter is invalid: LevenbergMarquardtParams::elimination");
|
throw runtime_error("Optimization parameter is invalid: LevenbergMarquardtParams::elimination");
|
||||||
|
}
|
||||||
|
|
||||||
if (lmVerbosity >= LevenbergMarquardtParams::TRYLAMBDA) cout << "linear delta norm = " << delta.vector().norm() << endl;
|
if (lmVerbosity >= LevenbergMarquardtParams::TRYLAMBDA) cout << "linear delta norm = " << delta.vector().norm() << endl;
|
||||||
if (lmVerbosity >= LevenbergMarquardtParams::TRYDELTA) delta.print("delta");
|
if (lmVerbosity >= LevenbergMarquardtParams::TRYDELTA) delta.print("delta");
|
||||||
|
|
|
@ -24,42 +24,44 @@ namespace gtsam {
|
||||||
|
|
||||||
class SuccessiveLinearizationParams : public NonlinearOptimizerParams {
|
class SuccessiveLinearizationParams : public NonlinearOptimizerParams {
|
||||||
public:
|
public:
|
||||||
/** See SuccessiveLinearizationParams::elimination */
|
/** See SuccessiveLinearizationParams::linearSolverType */
|
||||||
enum Elimination {
|
enum LinearSolverType {
|
||||||
MULTIFRONTAL,
|
MULTIFRONTAL_CHOLESKY,
|
||||||
SEQUENTIAL
|
MULTIFRONTAL_QR,
|
||||||
|
SEQUENTIAL_CHOLESKY,
|
||||||
|
SEQUENTIAL_QR,
|
||||||
|
SPCG
|
||||||
};
|
};
|
||||||
|
|
||||||
/** See SuccessiveLinearizationParams::factorization */
|
LinearSolverType linearSolverType; ///< The type of linear solver to use in the nonlinear optimizer
|
||||||
enum Factorization {
|
|
||||||
CHOLESKY,
|
|
||||||
QR,
|
|
||||||
};
|
|
||||||
|
|
||||||
Elimination elimination; ///< The elimination algorithm to use (default: MULTIFRONTAL)
|
|
||||||
Factorization factorization; ///< The numerical factorization (default: Cholesky)
|
|
||||||
boost::optional<Ordering> ordering; ///< The variable elimination ordering, or empty to use COLAMD (default: empty)
|
boost::optional<Ordering> ordering; ///< The variable elimination ordering, or empty to use COLAMD (default: empty)
|
||||||
|
|
||||||
SuccessiveLinearizationParams() :
|
SuccessiveLinearizationParams() : linearSolverType(MULTIFRONTAL_CHOLESKY) {}
|
||||||
elimination(MULTIFRONTAL), factorization(CHOLESKY) {}
|
|
||||||
|
|
||||||
virtual ~SuccessiveLinearizationParams() {}
|
virtual ~SuccessiveLinearizationParams() {}
|
||||||
|
|
||||||
virtual void print(const std::string& str = "") const {
|
virtual void print(const std::string& str = "") const {
|
||||||
NonlinearOptimizerParams::print(str);
|
NonlinearOptimizerParams::print(str);
|
||||||
if(elimination == MULTIFRONTAL)
|
switch ( linearSolverType ) {
|
||||||
std::cout << " elimination method: MULTIFRONTAL\n";
|
case MULTIFRONTAL_CHOLESKY:
|
||||||
else if(elimination == SEQUENTIAL)
|
std::cout << " linear solver type: MULTIFRONTAL CHOLESKY\n";
|
||||||
std::cout << " elimination method: SEQUENTIAL\n";
|
break;
|
||||||
else
|
case MULTIFRONTAL_QR:
|
||||||
std::cout << " elimination method: (invalid)\n";
|
std::cout << " linear solver type: MULTIFRONTAL QR\n";
|
||||||
|
break;
|
||||||
if(factorization == CHOLESKY)
|
case SEQUENTIAL_CHOLESKY:
|
||||||
std::cout << " factorization method: CHOLESKY\n";
|
std::cout << " linear solver type: SEQUENTIAL CHOLESKY\n";
|
||||||
else if(factorization == QR)
|
break;
|
||||||
std::cout << " factorization method: QR\n";
|
case SEQUENTIAL_QR:
|
||||||
else
|
std::cout << " linear solver type: SEQUENTIAL QR\n";
|
||||||
std::cout << " factorization method: (invalid)\n";
|
break;
|
||||||
|
case SPCG:
|
||||||
|
std::cout << " linear solver type: SPCG\n";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cout << " linear solver type: (invalid)\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(ordering)
|
if(ordering)
|
||||||
std::cout << " ordering: custom\n";
|
std::cout << " ordering: custom\n";
|
||||||
|
@ -69,13 +71,32 @@ public:
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
GaussianFactorGraph::Eliminate getEliminationFunction() const {
|
inline bool isMultifrontal() const {
|
||||||
if(factorization == SuccessiveLinearizationParams::CHOLESKY)
|
return (linearSolverType == MULTIFRONTAL_CHOLESKY) || (linearSolverType == MULTIFRONTAL_QR);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isSequential() const {
|
||||||
|
return (linearSolverType == SEQUENTIAL_CHOLESKY) || (linearSolverType == SEQUENTIAL_QR);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isSPCG() const {
|
||||||
|
return (linearSolverType == SPCG);
|
||||||
|
}
|
||||||
|
|
||||||
|
GaussianFactorGraph::Eliminate getEliminationFunction() {
|
||||||
|
switch (linearSolverType) {
|
||||||
|
case MULTIFRONTAL_CHOLESKY:
|
||||||
|
case MULTIFRONTAL_QR:
|
||||||
return EliminatePreferCholesky;
|
return EliminatePreferCholesky;
|
||||||
else if(factorization == SuccessiveLinearizationParams::QR)
|
|
||||||
|
case SEQUENTIAL_CHOLESKY:
|
||||||
|
case SEQUENTIAL_QR:
|
||||||
return EliminateQR;
|
return EliminateQR;
|
||||||
else
|
|
||||||
|
default:
|
||||||
throw runtime_error("Nonlinear optimization parameter \"factorization\" is invalid");
|
throw runtime_error("Nonlinear optimization parameter \"factorization\" is invalid");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -149,9 +149,9 @@ TEST( NonlinearOptimizer, SimpleDLOptimizer )
|
||||||
TEST( NonlinearOptimizer, optimization_method )
|
TEST( NonlinearOptimizer, optimization_method )
|
||||||
{
|
{
|
||||||
LevenbergMarquardtParams paramsQR;
|
LevenbergMarquardtParams paramsQR;
|
||||||
paramsQR.factorization = LevenbergMarquardtParams::QR;
|
paramsQR.linearSolverType = LevenbergMarquardtParams::MULTIFRONTAL_QR;
|
||||||
LevenbergMarquardtParams paramsChol;
|
LevenbergMarquardtParams paramsChol;
|
||||||
paramsChol.factorization = LevenbergMarquardtParams::CHOLESKY;
|
paramsChol.linearSolverType = LevenbergMarquardtParams::MULTIFRONTAL_CHOLESKY;
|
||||||
|
|
||||||
example::Graph fg = example::createReallyNonlinearFactorGraph();
|
example::Graph fg = example::createReallyNonlinearFactorGraph();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue