MOOCHO (Single Doxygen Collection) Version of the Day
MoochoPack_active_set_change.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines