composite.cc
Go to the documentation of this file.
1 /******************************************************************************
2 Copyright (c) 2017, Alexander W Winkler. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6 
7 * Redistributions of source code must retain the above copyright notice, this
8  list of conditions and the following disclaimer.
9 
10 * Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation
12  and/or other materials provided with the distribution.
13 
14 * Neither the name of the copyright holder nor the names of its
15  contributors may be used to endorse or promote products derived from
16  this software without specific prior written permission.
17 
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 ******************************************************************************/
29 
30 #include <ifopt/composite.h>
31 
32 #include <iostream>
33 #include <iomanip>
34 
35 namespace ifopt {
36 
37 Component::Component (int num_rows, const std::string& name)
38 {
39  num_rows_ = num_rows;
40  name_ = name;
41 }
42 
43 int
45 {
46  return num_rows_;
47 }
48 
49 void
50 Component::SetRows (int num_rows)
51 {
52  num_rows_ = num_rows;
53 }
54 
55 std::string
57 {
58  return name_;
59 }
60 
61 void Component::Print (double tol, int& index) const
62 {
63  // calculate squared bound violation
64  VectorXd x = GetValues();
65  VecBound bounds = GetBounds();
66 
67  std::vector<int> viol_idx;
68  for (std::size_t i=0; i<bounds.size(); ++i) {
69  double lower = bounds.at(i).lower_;
70  double upper = bounds.at(i).upper_;
71  double val = x(i);
72  if (val < lower-tol || upper+tol < val)
73  viol_idx.push_back(i); // constraint out of bounds
74  }
75 
76  std::string black = "\033[0m";
77  std::string red = "\033[31m";
78  std::string color = viol_idx.empty()? black : red;
79 
80  std::cout.precision(2);
81  std::cout << std::fixed
82  << std::left
83  << std::setw(30) << name_
84  << std::right
85  << std::setw(4) << num_rows_
86  << std::setw(9) << index
87  << std::setfill ('.')
88  << std::setw(7) << index+num_rows_-1
89  << std::setfill (' ')
90  << color
91  << std::setw(12) << viol_idx.size()
92  << black
93  << std::endl;
94 
95  index += num_rows_;
96 }
97 
98 Composite::Composite (const std::string& name, bool is_cost) :Component(0, name)
99 {
100  is_cost_ = is_cost;
101 }
102 
103 void
105 {
106  // at this point the number of rows must be specified.
107  assert(c->GetRows() != kSpecifyLater);
108 
109  components_.push_back(c);
110 
111  if (is_cost_)
112  SetRows(1);
113  else
114  SetRows(GetRows()+ c->GetRows());
115 }
116 
117 void
119 {
120  components_.clear();
121  SetRows(0);
122 }
123 
124 const Component::Ptr
125 Composite::GetComponent (std::string name) const
126 {
127  for (const auto& c : components_)
128  if (c->GetName() == name)
129  return c;
130 
131  assert(false); // component with name doesn't exist, abort program
132  return Component::Ptr();
133 }
134 
137 {
138  VectorXd g_all = VectorXd::Zero(GetRows());
139 
140  int row = 0;
141  for (const auto& c : components_) {
142  int n_rows = c->GetRows();
143  VectorXd g = c->GetValues();
144  g_all.middleRows(row, n_rows) += g;
145 
146  if (!is_cost_)
147  row += n_rows;
148  }
149  return g_all;
150 }
151 
152 void
154 {
155  int row = 0;
156  for (auto& c : components_) {
157  int n_rows = c->GetRows();
158  c->SetVariables(x.middleRows(row,n_rows));
159  row += n_rows;
160  }
161 }
162 
165 { // set number of variables only the first time this function is called,
166  // since number doesn't change during the optimization. Improves efficiency.
167  if (n_var == -1)
168  n_var = components_.empty() ? 0 : components_.front()->GetJacobian().cols();
169 
170  Jacobian jacobian(GetRows(), n_var);
171 
172  if (n_var == 0) return jacobian;
173 
174  int row = 0;
175  std::vector< Eigen::Triplet<double> > triplet_list;
176 
177  for (const auto& c : components_) {
178  const Jacobian& jac = c->GetJacobian();
179  triplet_list.reserve(triplet_list.size()+jac.nonZeros());
180 
181  for (int k=0; k<jac.outerSize(); ++k)
182  for (Jacobian::InnerIterator it(jac,k); it; ++it)
183  triplet_list.push_back(Eigen::Triplet<double>(row+it.row(), it.col(), it.value()));
184 
185  if (!is_cost_)
186  row += c->GetRows();
187  }
188 
189  jacobian.setFromTriplets(triplet_list.begin(), triplet_list.end());
190  return jacobian;
191 }
192 
195 {
196  VecBound bounds_;
197  for (const auto& c : components_) {
198  VecBound b = c->GetBounds();
199  bounds_.insert(bounds_.end(), b.begin(), b.end());
200  }
201 
202  return bounds_;
203 }
204 
207 {
208  return components_;
209 }
210 
211 void
213 {
214  int index = 0;
215  double tol = 0.001;
216 
217  std::cout << GetName() << ":\n";
218  for (auto c : components_) {
219  std::cout << " "; // indent components
220  c->Print(tol, index);
221  }
222  std::cout << std::endl;
223 }
224 
225 } /* namespace opt */
virtual VectorXd GetValues() const =0
Returns the "values" of whatever this component represents.
VecBound GetBounds() const override
Returns the "bounds" of this component.
Definition: composite.cc:194
virtual void Print(double tolerance, int &index_start) const
Prints the relevant information (name, rows, values) of this component.
Definition: composite.cc:61
std::string name_
Definition: composite.h:147
const Component::Ptr GetComponent(std::string name) const
Access generic component with the specified name.
Definition: composite.cc:125
static const int kSpecifyLater
Definition: composite.h:143
Component(int num_rows, const std::string &name)
Creates a component.
Definition: composite.cc:37
const ComponentVec GetComponents() const
Returns read access to the components.
Definition: composite.cc:206
std::vector< Component::Ptr > ComponentVec
Definition: composite.h:165
int GetRows() const
Returns the number of rows of this component.
Definition: composite.cc:44
void ClearComponents()
Removes all component from this composite.
Definition: composite.cc:118
std::shared_ptr< Component > Ptr
Definition: composite.h:65
std::string GetName() const
Returns the name (id) of this component.
Definition: composite.cc:56
Declares the classes Composite and Component used as variables, costs and constraints.
VectorXd GetValues() const override
Returns the "values" of whatever this component represents.
Definition: composite.cc:136
void SetRows(int num_rows)
Sets the number of rows of this component.
Definition: composite.cc:50
ComponentVec components_
Definition: composite.h:217
void AddComponent(const Component::Ptr &)
Adds a component to this composite.
Definition: composite.cc:104
Eigen::SparseMatrix< double, Eigen::RowMajor > Jacobian
Definition: composite.h:67
void PrintAll() const
Definition: composite.cc:212
common namespace for all elements in this library.
Definition: bounds.h:33
Interface representing either Variable, Cost or Constraint.
Definition: composite.h:63
void SetVariables(const VectorXd &x) override
Sets the optimization variables from an Eigen vector.
Definition: composite.cc:153
Jacobian GetJacobian() const override
Returns derivatives of each row w.r.t. the variables.
Definition: composite.cc:164
Composite(const std::string &name, bool is_cost)
Creates a Composite holding either variables, costs or constraints.
Definition: composite.cc:98
std::vector< Bounds > VecBound
Definition: composite.h:69
virtual VecBound GetBounds() const =0
Returns the "bounds" of this component.
Eigen::VectorXd VectorXd
Definition: composite.h:68


ifopt
Author(s): Alexander W. Winkler
autogenerated on Fri Sep 16 2022 02:15:26