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