MoochoPack_active_set_change.cpp

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

Generated on Thu Sep 18 12:35:16 2008 for MOOCHO (Single Doxygen Collection) by doxygen 1.3.9.1