44 #include "MoochoPack_ReducedHessianSecantUpdateLPBFGS_Strategy.hpp" 
   45 #include "MoochoPack_PBFGS_helpers.hpp" 
   46 #include "MoochoPack_NLPAlgo.hpp" 
   47 #include "MoochoPack_NLPAlgoState.hpp" 
   48 #include "ConstrainedOptPack_MatrixSymPosDefLBFGS.hpp" 
   49 #include "ConstrainedOptPack/src/AbstractLinAlgPack_MatrixSymPosDefCholFactor.hpp" 
   50 #include "ConstrainedOptPack/src/AbstractLinAlgPack_BFGS_helpers.hpp" 
   51 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_SpVectorClass.hpp" 
   52 #include "AbstractLinAlgPack_SpVectorOp.hpp" 
   53 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_MatrixOpOut.hpp" 
   54 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_GenPermMatrixSlice.hpp" 
   55 #include "AbstractLinAlgPack_GenPermMatrixSliceOp.hpp" 
   56 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_MatrixSymInitDiag.hpp" 
   57 #include "DenseLinAlgPack_LinAlgOpPack.hpp" 
   58 #include "Midynamic_cast_verbose.h" 
   59 #include "MiWorkspacePack.h" 
   61 namespace LinAlgOpPack {
 
   65 namespace MoochoPack {
 
   68   const proj_bfgs_updater_ptr_t&  proj_bfgs_updater
 
   74   : proj_bfgs_updater_(proj_bfgs_updater)
 
   75   , min_num_updates_proj_start_(min_num_updates_proj_start)
 
   76   , max_num_updates_proj_start_(max_num_updates_proj_start)
 
   77   , num_superbasics_switch_dense_(num_superbasics_switch_dense)
 
   78   , num_add_recent_updates_(num_add_recent_updates)
 
   82   DVectorSlice* s_bfgs, DVectorSlice* y_bfgs, 
bool first_update
 
   83   ,std::ostream& out, EJournalOutputLevel olevel, NLPAlgo *algo, NLPAlgoState *s
 
   91   namespace rcp = MemMngPack;
 
   93   using LinAlgOpPack::V_MtV;
 
   95   using AbstractLinAlgPack::norm_inf;
 
  101   if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  102     out << 
"\n*** (LPBFGS) Full limited memory BFGS to projected BFGS ...\n";
 
  106   MHSB_t &rHL_super = 
dynamic_cast<MHSB_t&
>(*rHL_k);
 
  108   MHSB_t &rHL_super = 
dyn_cast<MHSB_t>(*rHL_k);
 
  116   bool do_projected_rHL_RR = 
false;
 
  119   RCP<MatrixSymPosDefLBFGS> 
 
  120     lbfgs_rHL_RR = Teuchos::rcp_const_cast<MatrixSymPosDefLBFGS>(
 
  121       Teuchos::rcp_dynamic_cast<
const MatrixSymPosDefLBFGS>(rHL_super.B_RR_ptr()) );
 
  123   if( lbfgs_rHL_RR.get() && rHL_super.Q_R().is_identity()  ) {
 
  130       sTy = 
dot(*s_bfgs,*y_bfgs),
 
  131       yTy = 
dot(*y_bfgs,*y_bfgs);
 
  132     if( !ConstrainedOptPack::BFGS_sTy_suff_p_d(
 
  134       ,  
int(olevel) >= 
int(PRINT_ALGORITHM_STEPS) ? &out : NULL )
 
  135       && !proj_bfgs_updater().bfgs_update().use_dampening()
 
  138       if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  139         out << 
"\nWarning!  use_damening == false so there is no way we can perform any" 
  140             " kind of BFGS update (projected or not) so we will skip it!\n";
 
  142       quasi_newton_stats_(*s).set_k(0).set_updated_stats(
 
  143         QuasiNewtonStats::INDEF_SKIPED );
 
  147     const bool consider_switch  = lbfgs_rHL_RR->num_secant_updates() >= min_num_updates_proj_start();
 
  148     if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  149       out << 
"\nnum_previous_updates = " << lbfgs_rHL_RR->num_secant_updates()
 
  150         << ( consider_switch ? 
" >= " : 
" < " )
 
  151         << 
"min_num_updates_proj_start = " << min_num_updates_proj_start()
 
  153            ? 
"\nConsidering if we should switch to projected BFGS updating of superbasics ...\n" 
  154            : 
"\nNot time to consider switching to projected BFGS updating of superbasics yet!" );
 
  156     if( consider_switch ) {
 
  161       if( act_set_stats_(*s).updated_k(-1) ) {
 
  162         if( static_cast<int>(olevel) >= 
static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  163           out << 
"\nDetermining if projected BFGS updating of superbasics should begin ...\n";
 
  167           &nu_km1 = s->nu().get_k(-1);
 
  169           nu_indep = nu_km1(s->var_indep());
 
  172           = PBFGSPack::act_set_calmed_down(
 
  173             act_set_stats_(*s).get_k(-1)
 
  174             ,proj_bfgs_updater().act_set_frac_proj_start()
 
  177           max_num_updates_exceeded
 
  178           = lbfgs_rHL_RR->m_bar() >= max_num_updates_proj_start();
 
  179         do_projected_rHL_RR = act_set_calmed_down || max_num_updates_exceeded;
 
  180         if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  181           if( act_set_calmed_down ) {
 
  182             out << 
"\nThe active set has calmed down enough so lets further consider switching to\n" 
  183               << 
"projected BFGS updating of superbasic variables ...\n";
 
  185           else if( max_num_updates_exceeded ) {
 
  186             out << 
"\nThe active set has not calmed down enough but num_previous_updates = " 
  187               << lbfgs_rHL_RR->m_bar() << 
" >= max_num_updates_proj_start = " << max_num_updates_proj_start()
 
  188               << 
"\nso we will further consider switching to projected BFGS updating of superbasic variables ...\n";
 
  191             out << 
"\nIt is not time to switch to projected BFGS so just keep performing full limited memory BFGS for now ...\n";
 
  194         if( do_projected_rHL_RR ) {
 
  198           typedef Workspace<size_type>                              i_x_t;
 
  199           typedef Workspace<ConstrainedOptPack::EBounds>   bnd_t;
 
  200           i_x_t   i_x_free(wss,n_pz);
 
  201           i_x_t   i_x_fixed(wss,n_pz);
 
  202           bnd_t   bnd_fixed(wss,n_pz);
 
  203           i_x_t   l_x_fixed_sorted(wss,n_pz);
 
  207             rHL_scale = sTy > 0.0 ? yTy/sTy : 1.0;
 
  208           if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  209             out << 
"\nScaling for diagonal intitial rHL = rHL_scale*I, rHL_scale = " << rHL_scale << std::endl;
 
  211           value_type sRTBRRsR = 0.0, sRTyR = 0.0, sXTBXXsX = 0.0, sXTyX = 0.0;
 
  214           PBFGSPack::init_i_x_free_sRTsR_sRTyR(
 
  215             nu_indep, *s_bfgs, *y_bfgs
 
  216             , &n_pz_R, &i_x_free[0], &sRTBRRsR, &sRTyR );
 
  217           sRTBRRsR *= rHL_scale;
 
  218           Workspace<value_type> rHL_XX_diag_ws(wss,nu_indep.nz());
 
  219           DVectorSlice rHL_XX_diag(&rHL_XX_diag_ws[0],rHL_XX_diag_ws.size());
 
  220           rHL_XX_diag = rHL_scale;
 
  223           PBFGSPack::sort_fixed_max_cond_viol(
 
  224             nu_indep,*s_bfgs,*y_bfgs,rHL_XX_diag,sRTBRRsR,sRTyR
 
  225             ,&sXTBXXsX,&sXTyX,&l_x_fixed_sorted[0]);
 
  227           PBFGSPack::choose_fixed_free(
 
  228             proj_bfgs_updater().project_error_tol()
 
  229             ,proj_bfgs_updater().super_basic_mult_drop_tol(),nu_indep
 
  230             ,*s_bfgs,*y_bfgs,rHL_XX_diag,&l_x_fixed_sorted[0]
 
  231             ,olevel,out,&sRTBRRsR,&sRTyR,&sXTBXXsX,&sXTyX
 
  232             ,&n_pz_X,&n_pz_R,&i_x_free[0],&i_x_fixed[0],&bnd_fixed[0] );
 
  233           if( n_pz_R < n_pz ) {
 
  239               low_num_super_basics = n_pz_R <= num_superbasics_switch_dense();
 
  240             if( static_cast<int>(olevel) >= static_cast<int>(PRINT_BASIC_ALGORITHM_INFO) ) {
 
  241               out << 
"\nSwitching to projected BFGS updating ..." 
  242                 << 
"\nn_pz_R = " << n_pz_R << ( low_num_super_basics ? 
" <= " : 
" > " )
 
  243                 << 
" num_superbasics_switch_dense = " << num_superbasics_switch_dense()
 
  244                 << ( low_num_super_basics
 
  245                    ? 
"\nThere are not too many superbasic variables so use dense projected BFGS ...\n" 
  246                    : 
"\nThere are too many superbasic variables so use limited memory projected BFGS ...\n" 
  252             if( low_num_super_basics ) {
 
  253               rHL_RR = 
new MatrixSymPosDefCholFactor(
 
  257                 ,lbfgs_rHL_RR->maintain_original()
 
  258                 ,lbfgs_rHL_RR->maintain_inverse()
 
  262               rHL_RR = 
new MatrixSymPosDefLBFGS(
 
  263                 n_pz, lbfgs_rHL_RR->m()
 
  264                 ,lbfgs_rHL_RR->maintain_original()
 
  265                 ,lbfgs_rHL_RR->maintain_inverse()
 
  266                 ,lbfgs_rHL_RR->auto_rescaling()
 
  269             rHL_RR->init_identity( n_pz_R, rHL_scale );
 
  270             if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ITERATION_QUANTITIES) ) {
 
  271               out << 
"\nrHL_RR after intialized to rHL_RR = rHL_scale*I but before performing current BFGS update:\nrHL_RR =\n" 
  272                 << 
dynamic_cast<MatrixOp&
>(*rHL_RR); 
 
  277               &rHL_XX = 
dynamic_cast<MatrixSymInitDiag&
>(
 
  278                 const_cast<MatrixSymOp&
>(*rHL_super.B_XX_ptr()));
 
  281               &rHL_XX = 
dyn_cast<MatrixSymInitDiag>(
 
  282                 const_cast<MatrixSymOp&
>(*rHL_super.B_XX_ptr()));
 
  284             rHL_XX.init_identity( n_pz_X, rHL_scale );
 
  286             rHL_super.initialize(
 
  287               n_pz, n_pz_R, &i_x_free[0], &i_x_fixed[0], &bnd_fixed[0]
 
  288               ,Teuchos::rcp_const_cast<const MatrixSymWithOpFactorized>(
 
  289                 Teuchos::rcp_dynamic_cast<MatrixSymWithOpFactorized>(rHL_RR))
 
  296               &rHL_RR_op = 
dynamic_cast<MatrixSymOp&
>(*rHL_RR);
 
  297             const GenPermMatrixSlice
 
  298               &Q_R = rHL_super.Q_R(),
 
  299               &Q_X = rHL_super.Q_X();
 
  301             Workspace<value_type>
 
  302               y_bfgs_R_ws(wss,Q_R.cols()),
 
  303               s_bfgs_R_ws(wss,Q_R.cols()),
 
  304               y_bfgs_X_ws(wss,Q_X.cols()),
 
  305               s_bfgs_X_ws(wss,Q_X.cols());
 
  306             DVectorSlice y_bfgs_R(&y_bfgs_R_ws[0],y_bfgs_R_ws.size());
 
  307             DVectorSlice s_bfgs_R(&s_bfgs_R_ws[0],s_bfgs_R_ws.size());
 
  308             DVectorSlice y_bfgs_X(&y_bfgs_X_ws[0],y_bfgs_X_ws.size());
 
  309             DVectorSlice s_bfgs_X(&s_bfgs_X_ws[0],s_bfgs_X_ws.size());
 
  315             if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  316               out << 
"\nPerform current BFGS update on " << n_pz_R << 
" x " << n_pz_R << 
" projected " 
  317                 << 
"reduced Hessian for the superbasic variables where B = rHL_RR...\n";
 
  319             QuasiNewtonStats quasi_newton_stats;
 
  320             proj_bfgs_updater().bfgs_update().perform_update(
 
  321               &s_bfgs_R(),&y_bfgs_R(),
false,out,olevel,algo->algo_cntr().check_results()
 
  322               ,&rHL_RR_op, &quasi_newton_stats );
 
  324             if( lbfgs_rHL_RR->m_bar() ) {
 
  325               const size_type num_add_updates = std::_MIN(num_add_recent_updates(),lbfgs_rHL_RR->m_bar());
 
  326               if( static_cast<int>(olevel) >= 
static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  327                 out << 
"\nAdd the min(num_previous_updates,num_add_recent_updates) = min(" << lbfgs_rHL_RR->m_bar()
 
  328                   << 
"," << num_add_recent_updates() << 
") = " << num_add_updates << 
" most recent BFGS updates if possible ...\n";
 
  332                 project_error_tol = proj_bfgs_updater().project_error_tol();
 
  334                 S = lbfgs_rHL_RR->S(),
 
  335                 Y = lbfgs_rHL_RR->Y();
 
  337               for( 
size_type l = 1; l <= num_add_updates; ++l, --k ) {
 
  338                 if(k == 0) k = lbfgs_rHL_RR->m_bar();  
 
  343                 sRTyR    = 
dot( s_bfgs_R, y_bfgs_R );
 
  344                 sXTyX    = 
dot( s_bfgs_X, y_bfgs_X );
 
  346                   sXTyX_cond    = ::fabs(sXTyX/sRTyR) <= project_error_tol,
 
  347                   do_update     = sXTyX_cond,
 
  348                   sXTBXXsX_cond = 
false;
 
  354                   sXTBXXsX = rHL_scale * 
dot( s_bfgs_X, s_bfgs_X );
 
  355                   sXTBXXsX_cond = sXTBXXsX/sRTBRRsR <= project_error_tol;
 
  356                   do_update     = sXTBXXsX_cond && sXTyX_cond;
 
  358                 if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  359                   out << 
"\n---------------------------------------------------------------------" 
  360                     << 
"\nprevious update " << l
 
  361                     << 
"\n\nChecking projection error:\n" 
  362                     << 
"\n|s_X'*y_X|/|s_R'*y_R| = |" << sXTyX << 
"|/|" << sRTyR
 
  363                     << 
"| = " << ::fabs(sXTyX/sRTyR)
 
  364                     << ( sXTyX_cond ? 
" <= " : 
" > " ) << 
" project_error_tol = " 
  365                     << project_error_tol;
 
  367                     out << 
"\n(s_X'*rHL_XX*s_X/s_R'*rHL_RR*s_R) = (" << sXTBXXsX
 
  368                         << 
") = " << (sXTBXXsX/sRTBRRsR)
 
  369                         << ( sXTBXXsX_cond ? 
" <= " : 
" > " ) << 
" project_error_tol = " 
  370                         << project_error_tol;
 
  373                     ? 
"\n\nAttemping to add this previous update where B = rHL_RR ...\n" 
  374                     : 
"\n\nCan not add this previous update ...\n" );
 
  379                     proj_bfgs_updater().bfgs_update().perform_update(
 
  380                       &s_bfgs_R(),&y_bfgs_R(),
false,out,olevel,algo->algo_cntr().check_results()
 
  381                       ,&rHL_RR_op, &quasi_newton_stats );
 
  383                   catch( 
const MatrixSymSecant::UpdateSkippedException& excpt ) {
 
  384                     if( static_cast<int>(olevel) >= 
static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  385                       out << 
"\nOops!  The " << l << 
"th most recent BFGS update was rejected?:\n" 
  386                         << excpt.what() << std::endl;
 
  391               if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  392                 out << 
"\n---------------------------------------------------------------------\n";
 
  394               if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ITERATION_QUANTITIES) ) {
 
  395                 out << 
"\nrHL_RR after adding previous BFGS updates:\nrHL_BRR =\n" 
  396                   << 
dynamic_cast<MatrixOp&
>(*rHL_RR);
 
  400               if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  401                 out << 
"\nThere were no previous update vectors to add!\n";
 
  404             if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ITERATION_QUANTITIES) ) {
 
  405               out << 
"\nFull rHL after complete reinitialization:\nrHL =\n" << *rHL_k;
 
  407             quasi_newton_stats_(*s).set_k(0).set_updated_stats(
 
  408               QuasiNewtonStats::REINITIALIZED );
 
  412             if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  413               out << 
"\nn_pz_R == n_pz = " << n_pz_R << 
", No variables would be removed from " 
  414                 << 
"the superbasis so just keep on performing limited memory BFGS for now ...\n";
 
  416             do_projected_rHL_RR = 
false;
 
  422     if(!do_projected_rHL_RR) {
 
  423       if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  424         out << 
"\nPerform current BFGS update on " << n_pz << 
" x " << n_pz << 
" full " 
  425           << 
"limited memory reduced Hessian B = rHL ...\n";
 
  427       proj_bfgs_updater().bfgs_update().perform_update(
 
  428         s_bfgs,y_bfgs,first_update,out,olevel,algo->algo_cntr().check_results()
 
  430         ,&quasi_newton_stats_(*s).set_k(0)
 
  436     if( static_cast<int>(olevel) >= 
static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
 
  437       out << 
"\nWe have already switched to projected BFGS updating ...\n";
 
  444   return proj_bfgs_updater().perform_update(
 
  445     s_bfgs,y_bfgs,first_update,out,olevel,algo,s,rHL_k);
 
  451     << L << 
"*** Perform limited memory LBFGS updating initially then switch to dense\n" 
  452     << L << 
"*** projected BFGS updating when appropriate.\n" 
  453     << L << 
"ToDo: Finish implementation!\n";
 
bool perform_update(DVectorSlice *s_bfgs, DVectorSlice *y_bfgs, bool first_update, std::ostream &out, EJournalOutputLevel olevel, NLPAlgo *algo, NLPAlgoState *s, MatrixOp *rHL_k)
 
T_To & dyn_cast(T_From &from)
 
value_type transVtMtV(const Vector &v_rhs1, const MatrixOp &M_rhs2, BLAS_Cpp::Transp trans_rhs2, const Vector &v_rhs3)
 
ReducedHessianSecantUpdateLPBFGS_Strategy(const proj_bfgs_updater_ptr_t &proj_bfgs_updater=NULL, size_type min_num_updates_proj_start=0, size_type max_num_updates_proj_start=999999, size_type num_superbasics_switch_dense=500, size_type num_add_recent_updates=10)
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
 
void Vp_StMtV(VectorMutable *v_lhs, value_type alpha, const MatrixOp &M_rhs1, BLAS_Cpp::Transp trans_rhs1, const Vector &v_rhs2, value_type beta=1.0)
 
value_type dot(const Vector &v_rhs1, const Vector &v_rhs2)
 
void print_step(std::ostream &out, const std::string &leading_str) const 
 
TEUCHOSCORE_LIB_DLL_EXPORT Teuchos::RCP< WorkspaceStore > get_default_workspace_store()