composite.cc
Go to the documentation of this file.
00001 /******************************************************************************
00002 Copyright (c) 2017, Alexander W Winkler. All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 
00010 * Redistributions in binary form must reproduce the above copyright notice,
00011   this list of conditions and the following disclaimer in the documentation
00012   and/or other materials provided with the distribution.
00013 
00014 * Neither the name of the copyright holder nor the names of its
00015   contributors may be used to endorse or promote products derived from
00016   this software without specific prior written permission.
00017 
00018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00021 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00022 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00023 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00024 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00025 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00027 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028 ******************************************************************************/
00029 
00030 #include <ifopt/composite.h>
00031 
00032 #include <iostream>
00033 
00034 namespace ifopt {
00035 
00036 Component::Component (int num_rows, const std::string& name)
00037 {
00038   num_rows_ = num_rows;
00039   name_ = name;
00040 }
00041 
00042 int
00043 Component::GetRows () const
00044 {
00045   return num_rows_;
00046 }
00047 
00048 void
00049 Component::SetRows (int num_rows)
00050 {
00051   num_rows_ = num_rows;
00052 }
00053 
00054 std::string
00055 Component::GetName () const
00056 {
00057   return name_;
00058 }
00059 
00060 Composite::Composite (const std::string& name, bool is_cost) :Component(0, name)
00061 {
00062   is_cost_ = is_cost;
00063 }
00064 
00065 void
00066 Composite::AddComponent (const Component::Ptr& c)
00067 {
00068   // at this point the number of rows must be specified.
00069   assert(c->GetRows() != kSpecifyLater);
00070 
00071   components_.push_back(c);
00072 
00073   if (is_cost_)
00074     SetRows(1);
00075   else
00076     SetRows(GetRows()+ c->GetRows());
00077 }
00078 
00079 void
00080 Composite::ClearComponents ()
00081 {
00082   components_.clear();
00083   SetRows(0);
00084 }
00085 
00086 const Component::Ptr
00087 Composite::GetComponent (std::string name) const
00088 {
00089   for (const auto& c : components_)
00090     if (c->GetName() == name)
00091       return c;
00092 
00093   assert(false); // component with name doesn't exist, abort program
00094   return Component::Ptr();
00095 }
00096 
00097 Composite::VectorXd
00098 Composite::GetValues () const
00099 {
00100   VectorXd g_all = VectorXd::Zero(GetRows());
00101 
00102   int row = 0;
00103   for (const auto& c : components_) {
00104 
00105     int n_rows = c->GetRows();
00106     VectorXd g = c->GetValues();
00107     g_all.middleRows(row, n_rows) += g;
00108 
00109     if (!is_cost_)
00110       row += n_rows;
00111   }
00112   return g_all;
00113 }
00114 
00115 void
00116 Composite::SetVariables (const VectorXd& x)
00117 {
00118   int row = 0;
00119   for (auto& c : components_) {
00120 
00121     int n_rows = c->GetRows();
00122     c->SetVariables(x.middleRows(row,n_rows));
00123     row += n_rows;
00124   }
00125 }
00126 
00127 Composite::Jacobian
00128 Composite::GetJacobian () const
00129 {
00130   int n_var = components_.front()->GetJacobian().cols();
00131   Jacobian jacobian(GetRows(), n_var);
00132 
00133   int row = 0;
00134   for (const auto& c : components_) {
00135 
00136     const Jacobian& jac = c->GetJacobian();
00137     for (int k=0; k<jac.outerSize(); ++k)
00138       for (Jacobian::InnerIterator it(jac,k); it; ++it)
00139         jacobian.coeffRef(row+it.row(), it.col()) += it.value();
00140 
00141     if (!is_cost_)
00142       row += c->GetRows();
00143   }
00144 
00145   return jacobian;
00146 }
00147 
00148 Composite::VecBound
00149 Composite::GetBounds () const
00150 {
00151   VecBound bounds_;
00152   for (const auto& c : components_) {
00153     VecBound b = c->GetBounds();
00154     bounds_.insert(bounds_.end(), b.begin(), b.end());
00155   }
00156 
00157   return bounds_;
00158 }
00159 
00160 const Composite::ComponentVec
00161 Composite::GetComponents () const
00162 {
00163   return components_;
00164 }
00165 
00166 // some printouts for convenience
00167 static int print_counter = 0;
00168 void
00169 Composite::Print () const
00170 {
00171   print_counter = 0;
00172 
00173   std::cout << GetName() << ":\n";
00174   for (auto c : components_) {
00175     std::cout << "   "; // indent components
00176     c->Print();
00177   }
00178   std::cout << std::endl;
00179 }
00180 
00181 void Component::Print () const
00182 {
00183   int print_rows = 3;
00184   std::string end_string = ", ...";
00185 
00186   if (num_rows_ < print_rows) {
00187     print_rows = num_rows_;
00188     end_string.clear(); // all variables printed
00189   }
00190 
00191   // calculate squared bound violation
00192   VectorXd x = GetValues();
00193   VecBound bounds = GetBounds();
00194 
00195   std::vector<int> viol_idx;
00196   double eps = 0.001; // from ipopt config file
00197   for (uint i=0; i<bounds.size(); ++i) {
00198     double lower = bounds.at(i).lower_;
00199     double upper = bounds.at(i).upper_;
00200     double val = x(i);
00201     if (val < lower-eps || upper+eps < val)
00202       viol_idx.push_back(i); // constraint out of bounds
00203   }
00204 
00205 
00206   std::cout.precision(2);
00207   std::cout << std::fixed;
00208   // https://stackoverflow.com/questions/2616906/how-do-i-output-coloured-text-to-a-linux-terminal
00209   std::string black = "\033[0m";
00210   std::string red   = "\033[31m";
00211   std::string color = viol_idx.empty()? black : red;
00212   std::cout << name_ << "\t(";
00213   std::cout << num_rows_ << ", " << print_counter << "-" << print_counter+num_rows_;
00214   std::cout << ", " << color << "nr_violated=" << viol_idx.size() << " ( ";
00215   uint i_print = 4;
00216   int nr_indices_print = viol_idx.size()<i_print? viol_idx.size() : i_print;
00217   for (int i=0; i<nr_indices_print; ++i)
00218     std::cout << viol_idx.at(i) << ", ";
00219   std::cout << ")";
00220   std::cout << black;
00221   std::cout << ":\t";
00222 
00223   print_counter += num_rows_;
00224 
00225   VectorXd val = GetValues().topRows(print_rows);
00226   if (val.rows() > 0)
00227     std::cout << val(0);
00228   for (int i=1; i<val.rows(); ++i)
00229     std::cout << ",\t" << val(i);
00230 
00231   std::cout << end_string << std::endl;
00232 }
00233 
00234 } /* namespace opt */


ifopt_core
Author(s): Alexander W. Winkler
autogenerated on Sat Apr 21 2018 03:01:48