31 if (pointer->type() !=
"exotica::UnconstrainedEndPoseProblem")
33 ThrowNamed(
"This LevenbergMarquardtSolver can't solve problem of type '" << pointer->type() <<
"'!");
36 MotionSolver::SpecifyProblem(pointer);
45 if (parameters_.Alpha.size() > 1 && parameters_.Alpha.size() != prob_->N)
47 ThrowNamed(
"Wrong alpha dimension: alpha(" << parameters_.Alpha.size() <<
") != states(" << prob_->N <<
")")
51 JT_times_J_.resize(prob_->N, prob_->N);
54 yd_.resize(prob_->cost.S.rows());
55 cost_jacobian_.resize(prob_->cost.S.rows(), prob_->N);
57 if (parameters_.ScaleProblem ==
"none")
59 M_.setIdentity(prob_->N, prob_->N);
61 else if (parameters_.ScaleProblem ==
"Jacobian")
63 M_.setZero(prob_->N, prob_->N);
67 throw std::runtime_error(
"No ScaleProblem of type " + parameters_.ScaleProblem);
71 void LevenbergMarquardtSolver::Solve(Eigen::MatrixXd& solution)
73 if (!prob_)
ThrowNamed(
"Solver has not been initialized!");
75 prob_->ResetCostEvolution(GetNumberOfMaxIterations() + 1);
78 q_ = prob_->ApplyStartState();
79 if (prob_->N != q_.rows())
ThrowNamed(
"Wrong size q0 size=" << q_.rows() <<
", required size=" << prob_->N);
81 solution.resize(1, prob_->N);
83 lambda_ = parameters_.Damping;
84 for (
int i = 0; i < GetNumberOfMaxIterations(); ++i)
88 yd_.noalias() = prob_->cost.S * prob_->cost.ydiff;
92 error_ = prob_->GetScalarCost();
94 prob_->SetCostEvolution(i, error_);
96 cost_jacobian_.noalias() = prob_->cost.S * prob_->cost.jacobian;
101 if (error_ < error_prev_)
104 lambda_ = lambda_ / 10.0;
109 lambda_ = lambda_ * 10.0;
113 if (debug_)
HIGHLIGHT_NAMED(
"Levenberg-Marquardt",
"damping: " << lambda_);
115 if (parameters_.ScaleProblem ==
"Jacobian")
117 M_.diagonal().noalias() = (cost_jacobian_.transpose() * cost_jacobian_).diagonal();
120 JT_times_J_.noalias() = cost_jacobian_.transpose() * cost_jacobian_;
121 JT_times_J_ += lambda_ * M_;
123 llt_.compute(JT_times_J_);
124 if (llt_.info() != Eigen::Success)
126 ThrowPretty(
"Error during matrix decomposition of J^T * J (lambda=" << lambda_ <<
"):\n" 129 qd_.noalias() = cost_jacobian_.transpose() * yd_;
130 llt_.solveInPlace(qd_);
132 if (parameters_.Alpha.size() == 1)
134 q_ -= qd_ * parameters_.Alpha[0];
138 q_ -= qd_.cwiseProduct(parameters_.Alpha);
141 if (qd_.norm() < parameters_.Convergence)
143 if (debug_)
HIGHLIGHT_NAMED(
"Levenberg-Marquardt",
"Reached convergence (" << qd_.norm() <<
" < " << parameters_.Convergence <<
")");
148 solution.row(0) = q_;
#define REGISTER_MOTIONSOLVER_TYPE(TYPE, DERIV)
#define HIGHLIGHT_NAMED(name, x)
double GetDuration() const
std::shared_ptr< PlanningProblem > PlanningProblemPtr