117 inline int minimize(Foo& f, Vector& x, Scalar& fx,
const Vector& lb,
const Vector& ub)
122 const int n = x.size();
123 if (lb.size() != n || ub.size() != n)
124 throw std::invalid_argument(
"'lb' and 'ub' must have the same size as 'x'");
128 force_bounds(x, lb, ub);
134 const int fpast = m_param.past;
138 m_projgnorm = proj_grad_norm(x, m_grad, lb, ub);
146 if (m_projgnorm <= m_param.epsilon || m_projgnorm <= m_param.epsilon_rel * x.norm())
153 IndexSet newact_set, fv_set;
154 Cauchy<Scalar>::get_cauchy_point(m_bfgs, x, m_grad, lb, ub, xcp, vecc, newact_set, fv_set);
163 m_drt.noalias() = xcp - x;
166 constexpr Scalar eps = std::numeric_limits<Scalar>::epsilon();
168 Vector vecs(n), vecy(n);
175 m_gradp.noalias() = m_grad;
176 Scalar dg = m_grad.dot(m_drt);
179 Scalar step_max = max_step_size(x, m_drt, lb, ub);
188 if (dg >= Scalar(0) || step_max <= m_param.min_step)
191 m_drt.noalias() = xcp - x;
193 m_bfgs.reset(n, m_param.m);
195 dg = m_grad.dot(m_drt);
196 step_max = max_step_size(x, m_drt, lb, ub);
200 step_max = std::min(m_param.max_step, step_max);
201 Scalar step = Scalar(1);
202 step = std::min(step, step_max);
203 LineSearch<Scalar>::LineSearch(f, m_param, m_xp, m_drt, step_max, step, fx, m_grad, dg, x);
206 m_projgnorm = proj_grad_norm(x, m_grad, lb, ub);
213 if (m_projgnorm <= m_param.epsilon || m_projgnorm <= m_param.epsilon_rel * x.norm())
220 const Scalar fxd = m_fx[k % fpast];
221 if (k >= fpast && abs(fxd - fx) <= m_param.delta * std::max(std::max(abs(fx), abs(fxd)), Scalar(1)))
224 m_fx[k % fpast] = fx;
227 if (m_param.max_iterations != 0 && k >= m_param.max_iterations)
235 vecs.noalias() = x - m_xp;
236 vecy.noalias() = m_grad - m_gradp;
237 if (vecs.dot(vecy) > eps * vecy.squaredNorm())
238 m_bfgs.add_correction(vecs, vecy);
240 force_bounds(x, lb, ub);
241 Cauchy<Scalar>::get_cauchy_point(m_bfgs, x, m_grad, lb, ub, xcp, vecc, newact_set, fv_set);
249 SubspaceMin<Scalar>::subspace_minimize(m_bfgs, x, xcp, m_grad, lb, ub,
250 vecc, newact_set, fv_set, m_param.max_submin, m_drt);