|
MoochoPack : Framework for Large-Scale Optimization Algorithms Version of the Day
|
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 // This library is free software; you can redistribute it and/or modify 00013 // it under the terms of the GNU Lesser General Public License as 00014 // published by the Free Software Foundation; either version 2.1 of the 00015 // License, or (at your option) any later version. 00016 // 00017 // This library is distributed in the hope that it will be useful, but 00018 // WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 // Lesser General Public License for more details. 00021 // 00022 // You should have received a copy of the GNU Lesser General Public 00023 // License along with this library; if not, write to the Free Software 00024 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00025 // USA 00026 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00027 // 00028 // *********************************************************************** 00029 // @HEADER 00030 00031 #include <assert.h> 00032 00033 #include <iomanip> 00034 #include <ostream> 00035 00036 #include "MoochoPack_active_set_change.hpp" 00037 #include "AbstractLinAlgPack/src/AbstractLinAlgPack_SpVectorClass.hpp" 00038 00039 void MoochoPack::active_set_change( 00040 const SpVectorSlice& nu_k, const SpVectorSlice& nu_km1, Range1D indep 00041 ,EJournalOutputLevel olevel, std::ostream* out 00042 ,size_type* num_adds, size_type* num_drops 00043 ,size_type* num_active_indep, size_type* num_adds_indep, size_type* num_drops_indep 00044 ) 00045 { 00046 using std::setw; 00047 using std::endl; 00048 00049 const int w = 12; 00050 00051 *num_adds = *num_drops = *num_adds_indep = *num_drops_indep = 0; 00052 *num_active_indep = nu_k(indep).nz(); 00053 00054 if( !nu_k.nz() && !nu_km1.nz() ) 00055 return; 00056 00057 TEST_FOR_EXCEPT( !( nu_k.is_sorted() && nu_km1.is_sorted() ) ); 00058 00059 bool dump_change = (int)olevel >= (int)PRINT_ACTIVE_SET; 00060 00061 if( dump_change ) { 00062 *out 00063 << "\n*** Changes in active set\n\n" 00064 << setw(w) << "i" 00065 << setw(w) << "uplo" 00066 << setw(w) << "dep/indep" 00067 << setw(w) << "change\n" 00068 << setw(w) << "----------" 00069 << setw(w) << "----------" 00070 << setw(w) << "----------" 00071 << setw(w) << "----------\n"; 00072 } 00073 00074 SpVectorSlice::const_iterator 00075 nu_k_itr = nu_k.begin(), 00076 nu_k_end = nu_k.end(), 00077 nu_km1_itr = nu_km1.begin(), 00078 nu_km1_end = nu_km1.end(); 00079 00080 while( nu_k_itr != nu_k_end || nu_km1_itr != nu_km1_end ) { 00081 if( nu_k_itr != nu_k_end && ( nu_km1_itr == nu_km1_end || ( nu_k_itr != nu_k_end 00082 && nu_k_itr->indice()+nu_k.offset() < nu_km1_itr->indice()+nu_km1.offset() ) ) ) 00083 { 00084 // *nu_k_itr was added to active set. 00085 const size_type i = nu_k_itr->indice() + nu_k.offset(); 00086 const bool is_indep = indep.in_range(i); 00087 if(is_indep) 00088 (*num_adds_indep)++; 00089 (*num_adds)++; 00090 if(dump_change) 00091 *out 00092 << setw(w) << i 00093 << setw(w) << ( nu_k_itr->value() >= 0.0 ? "upper" : "lower" ) 00094 << setw(w) << ( is_indep ? "indep" : "dep" ) 00095 << setw(w) << "added" << endl; 00096 nu_k_itr++; 00097 } 00098 else if( nu_km1_itr != nu_km1_end && ( nu_k_itr == nu_k_end || ( nu_km1_itr != nu_km1_end 00099 && nu_k_itr->indice()+nu_k.offset() > nu_km1_itr->indice()+nu_km1.offset() ) ) ) 00100 { 00101 // *nu_km1_itr was removed from the active set. 00102 const size_type i = nu_km1_itr->indice() + nu_km1.offset(); 00103 const bool is_indep = indep.in_range(i); 00104 if(is_indep) 00105 (*num_drops_indep)++; 00106 (*num_drops)++; 00107 if(dump_change) 00108 *out 00109 << setw(w) << i 00110 << setw(w) << ( nu_km1_itr->value() >= 0.0 ? "upper" : "lower" ) 00111 << setw(w) << ( is_indep ? "indep" : "dep" ) 00112 << setw(w) << "dropped" << endl; 00113 nu_km1_itr++; 00114 } 00115 else { 00116 // same variable (but the bound may have changed) 00117 const size_type i = nu_k_itr->indice() + nu_k.offset(); 00118 const bool is_indep = indep.in_range(i); 00119 if( nu_k_itr->value() * nu_km1_itr->value() < 0.0 ) { 00120 // Switched bounds. 00121 if(is_indep) { 00122 (*num_adds_indep)++; 00123 (*num_drops_indep)++; 00124 } 00125 (*num_adds)++; 00126 (*num_drops)++; 00127 if(dump_change) 00128 *out 00129 << setw(w) << i 00130 << setw(w) << ( nu_k_itr->value() >= 0.0 ? "upper" : "lower" ) 00131 << setw(w) << ( is_indep ? "indep" : "dep" ) 00132 << setw(w) << "switch bnd" << endl; 00133 } 00134 nu_k_itr++; 00135 nu_km1_itr++; 00136 } 00137 } 00138 00139 // Output summary 00140 if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { 00141 *out 00142 << "\n*** Active set change summary\n" 00143 << "nact_old = " << nu_km1.nz() << endl 00144 << "nact_new = " << nu_k.nz() << endl 00145 << "num_adds = " << *num_adds << endl 00146 << "num_drops = " << *num_drops << endl 00147 << "nact_indep_old = " << nu_km1(indep).nz() << endl 00148 << "nact_indep_new = " << *num_active_indep << endl 00149 << "num_indep_adds = " << *num_adds_indep << endl 00150 << "num_indep_drops = " << *num_drops_indep << endl; 00151 } 00152 } 00153 00154 #endif // 0
1.7.4