46 #include "MoochoPack_InitFinDiffReducedHessian_Step.hpp"
47 #include "MoochoPack_moocho_algo_conversion.hpp"
48 #include "IterationPack_print_algorithm_step.hpp"
49 #include "NLPInterfacePack_NLPObjGrad.hpp"
50 #include "AbstractLinAlgPack_MatrixSymInitDiag.hpp"
51 #include "AbstractLinAlgPack_MatrixSymOp.hpp"
52 #include "AbstractLinAlgPack_MatrixOpOut.hpp"
55 #include "AbstractLinAlgPack_LinAlgOpPack.hpp"
56 #include "AbstractLinAlgPack_VectorMutable.hpp"
57 #include "AbstractLinAlgPack_VectorAuxiliaryOps.hpp"
58 #include "AbstractLinAlgPack_VectorOut.hpp"
59 #include "Teuchos_dyn_cast.hpp"
64 T my_max(
const T& v1,
const T& v2 ) {
return v1 > v2 ? v1 : v2; }
67 namespace MoochoPack {
73 ,value_type step_scale
75 :initialization_method_(initialization_method)
78 ,step_scale_(step_scale)
89 using LinAlgOpPack::V_MtV;
92 NLPAlgo &algo = rsqp_algo(_algo);
94 NLPObjGrad &nlp =
dyn_cast<NLPObjGrad>(algo.nlp());
96 EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level();
100 if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
101 using IterationPack::print_algorithm_step;
102 print_algorithm_step( algo, step_poss, type, assoc_step_poss, out );
106 IterQuantityAccess<index_type>
107 &num_basis_iq = s.num_basis();
109 const bool new_basis = num_basis_iq.updated_k(0);
110 const int k_last_offset = s.rHL().last_updated();
115 if( new_basis || k_last_offset == IterQuantity::NONE_UPDATED ) {
120 IterQuantityAccess<VectorMutable>
123 IterQuantityAccess<MatrixOp>
125 IterQuantityAccess<MatrixSymOp>
128 if( (
int)olevel >= (
int)PRINT_ALGORITHM_STEPS ) {
129 out <<
"\nReinitializing the reduced Hessain using a finite difference\n";
132 MatrixSymInitDiag &rHL_diag =
dyn_cast<MatrixSymInitDiag>(rHL_iq.set_k(0));
133 const MatrixOp &Z_k = Z_iq.get_k(0);
134 const Vector &x_k = x_iq.get_k(0);
135 const Vector &rGf_k = rGf_iq.get_k(0);
138 VectorSpace::vec_mut_ptr_t e = Z_k.space_rows().create_member(1.0);
141 VectorSpace::vec_mut_ptr_t Ze = x_k.space().create_member();
151 const value_type nrm_Ze = Ze->norm_inf();
152 value_type u = step_scale() / nrm_Ze;
154 if( (
int)olevel >= (
int)PRINT_ALGORITHM_STEPS ) {
155 out <<
"\n||Ze||inf = " << nrm_Ze << std::endl;
158 if( (
int)olevel >= (
int)PRINT_VECTORS ) {
159 out <<
"\nZe =\n" << *Ze;
162 if( algo.nlp().num_bounded_x() ) {
169 std::pair<value_type,value_type>
173 ,nlp.max_var_bounds_viol()
176 if( (
int)olevel >= (int)PRINT_ALGORITHM_STEPS ) {
177 out <<
"\nMaximum steps ( possitive, negative ) in bounds u = ("
178 << u_steps.first <<
"," << u_steps.second <<
")\n";
181 if( u_steps.first < u )
183 if( ::fabs(u_steps.second) < u )
187 if( (
int)olevel >= (int)PRINT_ALGORITHM_STEPS ) {
188 out <<
"\nFinite difference step length u = " << u << std::endl;
196 VectorSpace::vec_mut_ptr_t x_fd = x_k.space().create_member();
197 Vp_StV( x_fd.get(), u, *Ze );
200 VectorSpace::vec_mut_ptr_t Gf_fd = x_k.space().create_member();
201 nlp.unset_quantities();
202 nlp.set_Gf( Gf_fd.get() );
203 nlp.calc_Gf( *x_fd );
205 if( (
int)olevel >= (
int)PRINT_VECTORS ) {
206 out <<
"\nGf_fd =\n" << *Gf_fd;
210 VectorSpace::vec_mut_ptr_t rGf_fd = Z_k.space_rows().create_member();
214 Vp_StV( rGf_fd.get(), -1.0, rGf_k );
217 Vt_S( rGf_fd.get(), 1.0 / u );
220 nrm_rGf_fd = rGf_fd->norm_inf();
222 if( (
int)olevel >= (
int)PRINT_ALGORITHM_STEPS ) {
223 out <<
"\n||(rGf_fd - rGf_k)/u||inf = " << nrm_rGf_fd << std::endl;
225 if( (
int)olevel >= (
int)PRINT_VECTORS ) {
226 out <<
"\n(rGf_fd - rGf_k)/u =\n" << *rGf_fd;
229 if( nrm_rGf_fd <= min_diag() ) {
230 if( (
int)olevel >= (
int)PRINT_ALGORITHM_STEPS ) {
231 out <<
"\n||(rGf_fd - rGf_k)/u||inf = " << nrm_rGf_fd
232 <<
" < min_diag = " << min_diag() << std::endl
233 <<
"\nScale by min_diag ... \n";
235 rHL_diag.init_identity(Z_k.space_rows(),min_diag());
238 switch( initialization_method() ) {
239 case SCALE_IDENTITY: {
240 if( (
int)olevel >= (int)PRINT_ALGORITHM_STEPS ) {
241 out <<
"\nScale the identity matrix by ||(rGf_fd - rGf_k)/u||inf ... \n";
243 rHL_diag.init_identity(Z_k.space_rows(),nrm_rGf_fd);
247 case SCALE_DIAGONAL_ABS:
249 if( (
int)olevel >= (int)PRINT_ALGORITHM_STEPS ) {
250 out <<
"\nScale diagonal by modified finite difference ... \n";
257 min_ele = my_max( nrm_rGf_fd / max_cond(), min_diag() );
259 if( initialization_method() == SCALE_DIAGONAL )
264 if( (
int)olevel >= (int)PRINT_ALGORITHM_STEPS ) {
265 out <<
"\n||diag||inf = " << rGf_fd->norm_inf() << std::endl;
267 if( (
int)olevel >= (
int)PRINT_VECTORS ) {
268 out <<
"\ndiag =\n" << *rGf_fd;
270 rHL_diag.init_diagonal(*rGf_fd);
277 nlp.unset_quantities();
279 quasi_newton_stats_(s).set_k(0).set_updated_stats(
280 QuasiNewtonStats::REINITIALIZED );
282 if( (
int)olevel >= (
int)PRINT_ITERATION_QUANTITIES ) {
283 out <<
"\nrHL_k =\n" << rHL_iq.get_k(0);
294 ,std::ostream& out,
const std::string& L
298 << L <<
"*** Initialize the reduced Hessian using a single finite difference.\n"
299 << L <<
"*** Where the nlp must support the NLPObjGrad interface and\n"
300 << L <<
"*** rHL_k must support the MatrixSymInitDiag interface or exceptions\n"
301 << L <<
"*** will be thrown.\n"
302 << L <<
"default: num_basis_remembered = NO_BASIS_UPDATED_YET\n"
303 << L <<
" initialization_method = SCALE_DIAGONAL\n"
304 << L <<
" max_cond = " << max_cond() << std::endl
305 << L <<
" min_diag = " << min_diag() << std::endl
306 << L <<
" step_scale = " << step_scale() << std::endl
307 << L <<
"if num_basis_k is updated then\n"
308 << L <<
" new_basis = true\n"
310 << L <<
" new_basis = false\n"
312 << L <<
"if new_basis == true or no past rHL as been updated then\n"
313 << L <<
" *** Reinitialize the reduced Hessian using finite differences\n"
314 << L <<
" Ze = Z * e\n"
315 << L <<
" u = step_scale / norm(Ze,inf)\n"
316 << L <<
" if there are bounds on the problem then\n"
317 << L <<
" Find the largest (in magnitude) positive (u_pos) and\n"
318 << L <<
" negative (u_neg) step u where the slightly relaxed variable\n"
320 << L <<
" xl - delta <= x_k + u * Ze <= xu + delta\n"
321 << L <<
" are strictly satisfied (where delta = max_var_bounds_viol).\n"
322 << L <<
" if u_pos < u then\n"
323 << L <<
" u = u_pos\n"
325 << L <<
" if abs(u_neg) < u then\n"
326 << L <<
" u = u_neg\n"
329 << L <<
" x_fd = x_k + u * Ze\n"
330 << L <<
" rGf_fd = ( Z_k' * Gf(x_fd) - rGf_k ) / u\n"
331 << L <<
" if norm(rGf_fd,inf) <= min_diag then\n"
332 << L <<
" rHL_k = min_diag * eye(n-r)\n"
334 << L <<
" if initialization_method == SCALE_IDENTITY then\n"
335 << L <<
" rHL_k = norm(rGf_fd,inf) * eye(n-r)\n"
336 << L <<
" else if initialization_method == SCALE_DIAGONAL or SCALE_DIAGONAL_ABS then\n"
337 << L <<
" *** Make sure that all of the diagonal elements are\n"
338 << L <<
" *** positive and that the smallest element is\n"
339 << L <<
" *** no smaller than norm(rGf_fd,inf) / max_cond\n"
340 << L <<
" *** So that rHL_k will be positive definite an\n"
341 << L <<
" *** well conditioned\n"
342 << L <<
" min_ele = max( norm(rGf_fd,inf)/max_cond, min_diag )\n"
343 << L <<
" if initialization_method == SCALE_DIAGONAL then\n"
344 << L <<
" for i = 1 ... n-r\n"
345 << L <<
" diag(i) = max( rGf_fd(i), min_ele )\n"
347 << L <<
" else *** SCALE_DIAGONAL_ABS\n"
348 << L <<
" for i = 1 ... n-r\n"
349 << L <<
" diag(i) = max( abs(rGf_fd(i)), min_ele )\n"
352 << L <<
" rHL_k = diag(diag)\n"
void max_vec_scalar(value_type min_ele, VectorMutable *y)
void Vt_S(VectorMutable *v_lhs, const value_type &alpha)
bool do_step(Algorithm &algo, poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss)
void Vp_StV(VectorMutable *v_lhs, const value_type &alpha, const Vector &v_rhs)
T_To & dyn_cast(T_From &from)
void max_abs_vec_scalar(value_type min_ele, VectorMutable *y)
rSQP Algorithm control class.
virtual std::ostream & journal_out() const
void print_step(const Algorithm &algo, poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss, std::ostream &out, const std::string &leading_str) const
Reduced space SQP state encapsulation interface.
AlgorithmTracker & track()
std::pair< value_type, value_type > max_near_feas_step(const Vector &x, const Vector &d, const Vector &xl, const Vector &xu, value_type max_bnd_viol)
NLPAlgoState & rsqp_state()
<<std aggr>="">> members for algo_cntr
InitFinDiffReducedHessian_Step(EInitializationMethod initialization_method=SCALE_IDENTITY, value_type max_cond=1e+1, value_type min_diag=1e-8, value_type step_scale=1e-1)
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)