MoochoPack : Framework for Large-Scale Optimization Algorithms Version of the Day
MoochoPack_CheckBasisFromCPy_Step.cpp
00001 #if 0
00002 
00003 // @HEADER
00004 // ***********************************************************************
00005 // 
00006 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
00007 //                  Copyright (2003) Sandia Corporation
00008 // 
00009 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00010 // license for use of this work by or on behalf of the U.S. Government.
00011 // 
00012 // Redistribution and use in source and binary forms, with or without
00013 // modification, are permitted provided that the following conditions are
00014 // met:
00015 //
00016 // 1. Redistributions of source code must retain the above copyright
00017 // notice, this list of conditions and the following disclaimer.
00018 //
00019 // 2. Redistributions in binary form must reproduce the above copyright
00020 // notice, this list of conditions and the following disclaimer in the
00021 // documentation and/or other materials provided with the distribution.
00022 //
00023 // 3. Neither the name of the Corporation nor the names of the
00024 // contributors may be used to endorse or promote products derived from
00025 // this software without specific prior written permission.
00026 //
00027 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00028 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00030 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00031 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00032 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00033 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00034 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00035 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00036 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00037 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00038 //
00039 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 
00040 // 
00041 // ***********************************************************************
00042 // @HEADER
00043 
00044 #include <typeinfo>
00045 
00046 #include "MoochoPack/src/std/CheckBasisFromCPy_Step.h"
00047 #include "MoochoPack_moocho_algo_conversion.hpp"
00048 #include "IterationPack_print_algorithm_step.hpp"
00049 #include "ConstrainedOptPack_DecompositionSystemVarReduct.hpp"
00050 #include "ConstrainedOptPack/src/VectorWithNorms.h"
00051 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_MatrixOp.hpp"
00052 #include "DenseLinAlgPack_DVectorClass.hpp"
00053 #include "DenseLinAlgPack_DVectorOp.hpp"
00054 #include "DenseLinAlgPack_LinAlgOpPack.hpp"
00055 #include "Midynamic_cast_verbose.h"
00056 #include "MiWorkspacePack.h"
00057 
00058 namespace LinAlgOpPack {
00059   using AbstractLinAlgPack::Vp_StMtV;
00060 }
00061 
00062 namespace MoochoPack {
00063 
00064 CheckBasisFromCPy_Step::CheckBasisFromCPy_Step(
00065   const new_basis_strategy_ptr_t& new_basis_strategy
00066   ,value_type max_basis_cond_change_frac
00067   )
00068   : new_basis_strategy_(new_basis_strategy)
00069   , max_basis_cond_change_frac_( max_basis_cond_change_frac )
00070 {
00071   reset();
00072 }
00073 
00074 void CheckBasisFromCPy_Step::reset() {
00075   beta_min_ = std::numeric_limits<value_type>::max();
00076 }
00077 
00078 // Overridden
00079 
00080 bool CheckBasisFromCPy_Step::do_step( Algorithm& _algo, poss_type step_poss
00081   , IterationPack::EDoStepType type, poss_type assoc_step_poss )
00082 {
00083   using DenseLinAlgPack::norm_inf;
00084   using LinAlgOpPack::V_MtV;
00085   using LinAlgOpPack::Vp_V;
00086   using Teuchos::dyn_cast;
00087   using Teuchos::Workspace;
00088   Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00089 
00090   NLPAlgo &algo = rsqp_algo(_algo);
00091   NLPAlgoState  &s    = algo.rsqp_state();
00092   Range1D   decomp  = s.con_decomp();
00093 
00094   EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level();
00095   std::ostream& out = algo.track().journal_out();
00096 
00097   // print step header.
00098   if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
00099     using IterationPack::print_algorithm_step;
00100     print_algorithm_step( algo, step_poss, type, assoc_step_poss, out );
00101   }
00102 
00103   bool select_new_basis = false;
00104 
00105   // Compute: resid = (Gc(decomp)'*Y) * py + c(decomp)
00106   DVectorSlice                  py_k = s.py().get_k(0)();
00107   DVectorSlice                  c_k  = s.c().get_k(0)();
00108   DVectorSlice                  c_decomp_k  = c_k(decomp);
00109   Workspace<value_type>   resid_ws(wss,py_k.size());
00110   DVectorSlice                  resid(&resid_ws[0],resid_ws.size());
00111   {
00112 #ifdef _WINDOWS
00113     DecompositionSystemVarReduct
00114       &decomp_sys = dynamic_cast<DecompositionSystemVarReduct&>(s.decomp_sys());
00115 #else
00116     DecompositionSystemVarReduct
00117       &decomp_sys = dyn_cast<DecompositionSystemVarReduct>(s.decomp_sys());
00118 #endif
00119     V_MtV( &resid, decomp_sys.C(), BLAS_Cpp::no_trans, py_k );
00120     Vp_V( &resid, c_decomp_k );
00121   }
00122 
00123   const value_type
00124     small_num    = std::numeric_limits<value_type>::min(),
00125     nrm_resid    = norm_inf(resid),
00126     nrm_c_decomp = norm_inf(c_decomp_k),
00127     beta         = nrm_resid / (nrm_c_decomp+small_num);
00128 
00129   if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) {
00130     out << "\nbeta = ||(Gc(decomp)'*Y)*py_k + c_k(decomp)||inf / (||c_k(decomp)||inf + small_number)"
00131       << "\n     = "<<nrm_resid<<" / ("<<nrm_c_decomp<<" + "<<small_num<<")"
00132       << "\n     = " << beta << std::endl;
00133   }
00134   
00135   if( beta != 0.0 ) {
00136     if( beta < beta_min_ ) {
00137       beta_min_ = beta;
00138     }
00139     else {
00140       if( beta / beta_min_ > max_basis_cond_change_frac() ) {
00141         if( (int)olevel >= (int)PRINT_BASIC_ALGORITHM_INFO ) {
00142           out
00143             << "\nbeta_change = ( ||R*py+c||/||c|| = " << beta
00144             << " ) / ( min ||R*py+c||/||c|| = " << beta_min_ << " )\n"
00145             << "              = " << (beta/beta_min_) << " > max_basis_cond_change_frac = "
00146             << max_basis_cond_change_frac()
00147             << "\n\nSelecting a new basis"
00148             << " (k = " << algo.state().k() << ") ...\n";
00149         }
00150         select_new_basis = true;
00151       }
00152     }
00153     if(select_new_basis) {
00154       // reset memory
00155       // ToDo: You really need to check to see if someone else
00156       //     changed the basis also.
00157       beta_min_ = std::numeric_limits<value_type>::max();
00158       return new_basis_strategy().transistion_basis(algo,step_poss,type,assoc_step_poss);
00159     }
00160   }
00161   return true;
00162 }
00163 
00164 void CheckBasisFromCPy_Step::print_step( const Algorithm& algo, poss_type step_poss
00165   , IterationPack::EDoStepType type, poss_type assoc_step_poss
00166   , std::ostream& out, const std::string& L ) const
00167 {
00168   out
00169     << L << "*** Try to detect when the basis is becomming illconditioned\n"
00170     << L << "default: beta_min = inf\n"
00171     << L << "         max_basis_cond_change_frac = " << max_basis_cond_change_frac() << std::endl
00172     << L << "beta = norm_inf((Gc(decomp)'*Y)*py_k + c_k(decomp)) / (norm_inf(c_k(decomp))+small_number)\n"
00173     << L << "select_new_basis = false\n"
00174     << L << "if beta < beta_min then\n"
00175     << L << "    beta_min = beta\n"
00176     << L << "else\n"
00177     << L << "    if beta/ beta_min > max_basis_cond_change_frac then\n"
00178     << L << "        select_new_basis = true\n"
00179     << L << "    end\n"
00180     << L << "end\n"
00181     << L << "if select_new_basis == true then\n"
00182     << L << "    new basis selection : " << typeName(new_basis_strategy()) << std::endl;
00183   new_basis_strategy().print_method( rsqp_algo(algo),step_poss,type,assoc_step_poss,out
00184     ,L+"        " );
00185   out
00186     << L << "    end new basis selection\n"
00187     << L << "end\n";
00188 }
00189 
00190 } // end namespace MoochoPack 
00191 
00192 #endif // 0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends