ConstrainedOptPack: C++ Tools for Constrained (and Unconstrained) Optimization Version of the Day
ConstrainedOptPack_QPInitFixedFreeStd.cpp
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 <assert.h>
00043 
00044 #include <sstream>
00045 
00046 #include "ConstrainedOptPack_QPInitFixedFreeStd.hpp"
00047 #include "ConstrainedOptPack_initialize_Q_R_Q_X.hpp"
00048 
00049 namespace ConstrainedOptPack {
00050 namespace QPSchurPack {
00051 
00052 QPInitFixedFreeStd::QPInitFixedFreeStd()
00053   :n_(0)
00054   ,n_R_(0)
00055   ,m_(0)
00056   ,G_(NULL)
00057   ,A_(NULL)
00058   ,Ko_(NULL)
00059   ,constraints_(NULL)
00060 {}
00061 
00062 void QPInitFixedFreeStd::initialize(
00063   const DVectorSlice                   &g
00064   ,const MatrixSymOp              &G
00065   ,const MatrixOp                 *A
00066   ,size_type                          n_R
00067   ,const size_type                    i_x_free[]
00068   ,const size_type                    i_x_fixed[]
00069   ,const EBounds                      bnd_fixed[]
00070   ,const DVectorSlice                  &b_X
00071   ,const MatrixSymOpNonsing    &Ko
00072   ,const DVectorSlice                  &fo
00073   ,Constraints                        *constraints
00074   ,std::ostream                       *out
00075   ,bool                               test_setup
00076   ,value_type                         warning_tol
00077   ,value_type                         error_tol
00078   ,bool                               print_all_warnings
00079   )
00080 {
00081   namespace GPMSTP = AbstractLinAlgPack::GenPermMatrixSliceIteratorPack;
00082 
00083   if(!constraints)
00084     throw std::invalid_argument( "QPInitFixedFreeStd::initialize(...) : Error, "
00085       "constraints == NULL is not allowed." );
00086 
00087   // Validate the sizes of the input arguments
00088   const size_type
00089     n = constraints->n(),
00090     n_X = n - n_R;
00091   if( n_R > n )
00092     throw std::invalid_argument( "QPInitFixedFreeStd::initialize(...) : Error, "
00093       "n_R > constraints->n() is not allowed." );
00094   if(g.dim() !=n)
00095     throw std::invalid_argument( "QPInitFixedFreeStd::initialize(...) : Error, "
00096       "g.dim() != constraints->n()." );
00097   if(G.rows() != n || G.cols() !=  n)
00098     throw std::invalid_argument( "QPInitFixedFreeStd::initialize(...) : Error, "
00099       "G.rows() != constraints->n() or G.cols() !=  constraints->n()." );
00100   size_type
00101     m = 0;
00102   if(A) {
00103     m = A->cols();
00104     if( A->rows() != n )
00105       throw std::invalid_argument( "QPInitFixedFreeStd::initialize(...) : Error, "
00106         "A->rows() != constraints->n()." );
00107   }
00108   if(b_X.dim() != n_X)
00109     throw std::invalid_argument( "QPInitFixedFreeStd::initialize(...) : Error, "
00110       "b_X.dim() != constraints->n() - n_R." );
00111   if(Ko.rows() != n_R+m || Ko.cols() !=  n_R+m)
00112     throw std::invalid_argument( "QPInitFixedFreeStd::initialize(...) : Error, "
00113       "Ko.rows() != n_R+A->cols() or Ko.cols() !=  n_R+A->cols()." );
00114   if(fo.dim() != n_R+m)
00115     throw std::invalid_argument( "QPInitFixedFreeStd::initialize(...) : Error, "
00116       "fo.dim() != n_R+A->cols()." );
00117 
00118   // Setup x_init, l_x_X_map, i_x_X_map
00119 
00120   const int NOT_SET_YET = -9999; // Can't be FREE, LOWER, UPPER, or EQUALITY
00121   if(test_setup)
00122     x_init_.assign( n, (EBounds)NOT_SET_YET );
00123   else
00124     x_init_.resize(n);
00125   l_x_X_map_.assign(n,0);
00126   i_x_X_map_.assign(n_X,0);
00127 
00128   // Set free portion of x_init
00129   if( i_x_free == NULL ) {
00130     for( size_type i = 0; i < n_R; ++i )
00131       x_init_[i] = FREE;
00132   }
00133   else {
00134     if(test_setup) {
00135       for( const size_type *i_x_R = i_x_free; i_x_R != i_x_free + n_R; ++i_x_R ) {
00136         if( *i_x_R < 1 || *i_x_R > n ) {
00137           std::ostringstream omsg;
00138           omsg
00139             << "QPInitFixedFreeStd::initialize(...) : Error, "
00140             << "i_x_free[" << i_x_R-i_x_free << "] = "
00141             << (*i_x_R) << " is out of bounds";
00142           throw std::invalid_argument( omsg.str() );
00143         }
00144         if( x_init_(*i_x_R) != NOT_SET_YET ) {
00145           std::ostringstream omsg;
00146           omsg
00147             << "QPInitFixedFreeStd::initialize(...) : Error, "
00148             << "Duplicate entries for i_x_free[i] = "
00149             << (*i_x_R);
00150           throw std::invalid_argument( omsg.str() );
00151         }
00152         x_init_(*i_x_R) = FREE;
00153       }
00154     }
00155     else {
00156       for( const size_type *i_x_R = i_x_free; i_x_R != i_x_free + n_R; ++i_x_R ) {
00157         x_init_(*i_x_R) = FREE;
00158       }
00159     }
00160   }
00161 
00162   // Setup the fixed portion of x_init and l_x_X_map and i_x_X_map
00163   {
00164     const size_type
00165       *i_x_X = i_x_fixed;
00166     const EBounds
00167       *bnd = bnd_fixed;
00168     i_x_X_map_t::iterator
00169       i_x_X_map_itr = i_x_X_map_.begin();
00170     if(test_setup) {
00171       for( size_type l = 1; l <= n_X; ++l, ++i_x_X, ++bnd, ++i_x_X_map_itr ) {
00172         if( *i_x_X < 1 || *i_x_X > n ) {
00173           std::ostringstream omsg;
00174           omsg
00175             << "QPInitFixedFreeStd::initialize(...) : Error, "
00176             << "i_x_fixed[" << i_x_X-i_x_fixed << "] = "
00177             << (*i_x_X) << " is out of bounds";
00178           throw std::invalid_argument( omsg.str() );
00179         }
00180         if( *bnd == FREE ) {
00181           std::ostringstream omsg;
00182           omsg
00183             << "QPInitFixedFreeStd::initialize(...) : Error, "
00184             << "bnd_fixed[" << l-1 << "] can not equal FREE";
00185           throw std::invalid_argument( omsg.str() );
00186         }
00187         if( x_init_(*i_x_X) != NOT_SET_YET ) {
00188           std::ostringstream omsg;
00189           omsg
00190             << "QPInitFixedFreeStd::initialize(...) : Error, "
00191             << "Duplicate entries for i_x_fixed[i] = "
00192             << (*i_x_X);
00193           throw std::invalid_argument( omsg.str() );
00194         }
00195         x_init_(*i_x_X) = *bnd;
00196         l_x_X_map_(*i_x_X) = l;
00197         *i_x_X_map_itr = *i_x_X;
00198       }
00199       // Check that x_init was filled up properly
00200       for( size_type i = 1; i <= n; ++i ) {
00201         if( x_init_(i) == NOT_SET_YET ) {
00202           std::ostringstream omsg;
00203           omsg
00204             << "QPInitFixedFreeStd::initialize(...) : Error, "
00205             << "x_init(" << i << ") has not been set by"
00206                " i_x_free[] or i_x_fixed[].";
00207           throw std::invalid_argument( omsg.str() );
00208         }
00209       }
00210     }
00211     else {
00212       for( size_type l = 1; l <= n_X; ++l, ++i_x_X, ++bnd, ++i_x_X_map_itr ) {
00213         x_init_(*i_x_X) = *bnd;
00214         l_x_X_map_(*i_x_X) = l;
00215         *i_x_X_map_itr = *i_x_X;
00216       }
00217     }
00218   }
00219 
00220   // Setup Q_R and Q_X
00221   Q_R_row_i_.resize( i_x_free ? n_R : 0 );
00222   Q_R_col_j_.resize( i_x_free ? n_R : 0 );
00223   Q_X_row_i_.resize(n_X);
00224   Q_X_col_j_.resize(n_X);
00225   initialize_Q_R_Q_X(
00226     n_R,n_X,i_x_free,i_x_fixed,test_setup
00227     ,n_R && i_x_free ? &Q_R_row_i_[0] : NULL
00228     ,n_R && i_x_free ? &Q_R_col_j_[0] : NULL
00229     ,&Q_R_
00230     ,n_X ? &Q_X_row_i_[0] : NULL
00231     ,n_X ? &Q_X_col_j_[0] : NULL
00232     ,&Q_X_
00233   );
00234 
00235   // Setup other arguments
00236   n_        = n;
00237   n_R_      = n_R;
00238   m_        = m;
00239   g_.bind(const_cast<DVectorSlice&>(g));
00240   G_        = &G;
00241   A_        = A;
00242   b_X_.bind(const_cast<DVectorSlice&>(b_X));
00243   Ko_       = &Ko;
00244   fo_.bind(const_cast<DVectorSlice&>(fo));
00245   constraints_  = constraints;
00246 }
00247 
00248 // Overridden from QP 
00249 
00250 size_type QPInitFixedFreeStd::n() const
00251 {
00252   assert_initialized();
00253   return n_;
00254 }
00255 
00256 size_type QPInitFixedFreeStd::m() const
00257 {
00258   assert_initialized();
00259   return m_;
00260 }
00261 
00262 const DVectorSlice QPInitFixedFreeStd::g() const
00263 {
00264   assert_initialized();
00265   return g_;
00266 }
00267 
00268 const MatrixSymOp& QPInitFixedFreeStd::G() const
00269 {
00270   assert_initialized();
00271   return *G_;
00272 }
00273 
00274 const MatrixOp& QPInitFixedFreeStd::A() const
00275 {
00276   TEUCHOS_TEST_FOR_EXCEPT( !( A_ ) ); // ToDo: make this throw an exception
00277   return *A_;
00278 }
00279 
00280 size_type QPInitFixedFreeStd::n_R() const
00281 {
00282   assert_initialized();
00283   return n_R_;
00284 }
00285 
00286 const QP::x_init_t& QPInitFixedFreeStd::x_init() const
00287 {
00288   assert_initialized();
00289   return x_init_;
00290 }
00291 
00292 const QP::l_x_X_map_t& QPInitFixedFreeStd::l_x_X_map() const
00293 {
00294   assert_initialized();
00295   return l_x_X_map_;
00296 }
00297 
00298 const QP::i_x_X_map_t& QPInitFixedFreeStd::i_x_X_map() const
00299 {
00300   assert_initialized();
00301   return i_x_X_map_;
00302 }
00303 
00304 const DVectorSlice QPInitFixedFreeStd::b_X() const
00305 {
00306   assert_initialized();
00307   return b_X_;
00308 }
00309 
00310 const GenPermMatrixSlice& QPInitFixedFreeStd::Q_R() const
00311 {
00312   assert_initialized();
00313   return Q_R_;
00314 }
00315 
00316 const GenPermMatrixSlice& QPInitFixedFreeStd::Q_X() const
00317 {
00318   assert_initialized();
00319   return Q_X_;
00320 }
00321 
00322 const MatrixSymOpNonsing& QPInitFixedFreeStd::Ko() const
00323 {
00324   assert_initialized();
00325   return *Ko_;
00326 }
00327 
00328 const DVectorSlice QPInitFixedFreeStd::fo() const
00329 {
00330   assert_initialized();
00331   return fo_;
00332 }
00333 
00334 Constraints& QPInitFixedFreeStd::constraints()
00335 {
00336   assert_initialized();
00337   return *constraints_;
00338 }
00339 
00340 const Constraints& QPInitFixedFreeStd::constraints() const
00341 {
00342   assert_initialized();
00343   return *constraints_;
00344 }
00345 
00346 // private member functions
00347 
00348 void QPInitFixedFreeStd::assert_initialized() const
00349 {
00350   if( !n_ )
00351     throw std::logic_error( "QPInitFixedFreeStd::assert_initialized(), Error "
00352       "object not initialized\n" );
00353 }
00354 
00355 } // end namespace QPSchurPack
00356 } // end namespace ConstrainedOptPack 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends