test_levenberg_marquardt_dense_hyper_graph.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement
4  *
5  * Copyright (c) 2017,
6  * TU Dortmund - Institute of Control Theory and Systems Engineering.
7  * All rights reserved.
8  *
9  * This software is currently not released.
10  * Redistribution and use in source and binary forms,
11  * with or without modification, are prohibited.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
16  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
17  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
23  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24  * POSSIBILITY OF SUCH DAMAGE.
25  *
26  * Authors: Christoph Rösmann
27  *********************************************************************/
28 
30 
31 #include <corbo-optimization/hyper_graph/base_edge.h>
34 
35 #include <corbo-core/console.h>
36 #include <corbo-core/macros.h>
37 #include <corbo-core/utilities.h>
39 
40 #include <array>
41 #include <functional>
42 
43 #include "gtest/gtest.h"
44 
46 using corbo::HyperGraph2;
52 
53 class TestLevenbergMarquardtDenseHyperGraph : public testing::Test
54 {
55  protected:
56  // You can do set-up work for each test here.
58  // You can do clean-up work that doesn't throw exceptions here.
60  // If the constructor and destructor are not enough for setting up
61  // and cleaning up each test, you can define the following methods:
62 
63  // Code here will be called immediately after the constructor (right
64  // before each test).
65  void SetUp() override
66  {
67  // configure hyper graph
68  graph.setEdgeIterationStrategy(false);
69  // set retain lsq_form to true (required by LM)
70  graph.setRetainLsqForm(true);
71 
72  // configure solver
73  solver.setIterations(100);
74  }
75  // Code here will be called immediately after each test (right
76  // before the destructor).
77  // virtual void TearDown()
78 
79  HyperGraph2 graph;
80 
82 };
83 
85 {
86  // Vertices
87  VectorVertex v1(1);
88  v1.values().setOnes();
89  graph.addVertex(&v1);
90 
91  // Edges
93 
94  // create some edges types
95  auto edge_fun = [](const EdgeT::VertexContainer& vertices) { return vertices[0]->getData()[0] - 2; };
96 
97  EdgeInterface::UPtr edge(new EdgeT(edge_fun, true, v1));
98  graph.addObjectiveEdge(std::move(edge));
99 
100  EXPECT_TRUE(solver.initialize(graph));
101 
102  bool success = solver.solve(graph, true);
103 
104  EXPECT_TRUE(success);
105  EXPECT_NEAR(v1.values()[0], 2.0, 1e-6);
106 }
107 
109 {
110  // Vertices
111  VectorVertex v1(1);
112  v1.values().setOnes();
113  VectorVertex v2(Eigen::Vector2d(1, 1));
114  graph.addVertex(&v1);
115  graph.addVertex(&v2);
116 
117  // Edges
119 
120  auto edge_fun = [](const EdgeT::VertexContainer& vertices, Eigen::Ref<EdgeT::ErrorVector> values) {
121  values[0] = vertices[0]->getData()[0] - 5;
122  values[1] = vertices[1]->getData()[0] + 3;
123  values[2] = vertices[1]->getData()[1];
124  };
125 
126  EdgeInterface::UPtr edge(new EdgeT(edge_fun, true, v1, v2));
127  graph.addObjectiveEdge(std::move(edge));
128 
129  EXPECT_TRUE(solver.initialize(graph));
130 
131  bool success = solver.solve(graph, true);
132 
133  EXPECT_TRUE(success);
134  EXPECT_NEAR(v1.values()[0], 5.0, 1e-6);
135  EXPECT_NEAR(v2.values()[0], -3.0, 1e-6);
136  EXPECT_NEAR(v2.values()[1], 0.0, 1e-6);
137 }
138 
140 {
141  // Vertices
142  VectorVertex v1(1);
143  v1.values().setOnes();
144  pfVectorVertex v2(Eigen::Vector2d(1, 1));
145  graph.addVertex(&v1);
146  graph.addVertex(&v2);
147 
148  v1.setFixed(true);
149  v2.setFixed(0, true);
150 
151  // Edges
153 
154  auto edge_fun = [](const EdgeT::VertexContainer& vertices, Eigen::Ref<EdgeT::ErrorVector> values) {
155  values[0] = vertices[0]->getData()[0] - 5;
156  values[1] = vertices[1]->getData()[0] + 3;
157  values[2] = vertices[1]->getData()[1];
158  };
159 
160  EdgeInterface::UPtr edge(new EdgeT(edge_fun, true, v1, v2));
161  graph.addObjectiveEdge(std::move(edge));
162 
163  EXPECT_TRUE(solver.initialize(graph));
164 
165  bool success = solver.solve(graph, true);
166 
167  EXPECT_TRUE(success);
168  EXPECT_NEAR(v1.values()[0], 1.0, 1e-6);
169  EXPECT_NEAR(v2.values()[0], 1.0, 1e-6);
170  EXPECT_NEAR(v2.values()[1], 0.0, 1e-6);
171 }
172 
174 {
175  // Add variables
176  VectorVertex x1(1);
177  VectorVertex x2(1);
178 
179  x1.values()[0] = 5;
180  x2.values()[0] = -5;
181 
182  graph.addVertex(&x1);
183  graph.addVertex(&x2);
184 
185  // Create edges for minimizing 0.5 * (100*(x2-x1^2)^2 + (1-x1)^2 ) => f1^2 + f2^2
186 
187  // start with f1
189  auto edge_fun1 = [](const Edge1T::VertexContainer& vertices) {
190  double x1 = vertices[0]->getData()[0];
191  double x2 = vertices[1]->getData()[0];
192  return std::sqrt(100) * (x2 - x1 * x1);
193  };
194 
195  EdgeInterface::UPtr edge1(new Edge1T(edge_fun1, true, x1, x2));
196  graph.addObjectiveEdge(std::move(edge1));
197 
198  // now create f2
199  using Edge2T = EdgeGenericScalarFun<VectorVertex>;
200  auto edge_fun2 = [](const Edge2T::VertexContainer& vertices) {
201  double x1 = vertices[0]->getData()[0];
202  return 1 - x1;
203  };
204 
205  EdgeInterface::UPtr edge2(new Edge2T(edge_fun2, true, x1));
206  graph.addObjectiveEdge(std::move(edge2));
207 
208  EXPECT_TRUE(solver.initialize(graph));
209 
210  // now solve
211  bool success = solver.solve(graph, true);
212 
213  EXPECT_TRUE(success);
214  EXPECT_NEAR(x1.values()[0], 1.0, 1e-3);
215  EXPECT_NEAR(x2.values()[0], 1.0, 1e-3);
216 }
217 
219 {
220  // Vertices
221  VectorVertex v1(1);
222  v1.values().setOnes();
223  graph.addVertex(&v1);
224 
225  // Edges
227 
228  // create some edges types
229  auto edge_fun = [](const EdgeT::VertexContainer& vertices) { return vertices[0]->getData()[0] - 2; };
230  EdgeInterface::UPtr edge1(new EdgeT(edge_fun, true, v1));
231  graph.addObjectiveEdge(std::move(edge1));
232 
233  auto eq_constr = [](const EdgeT::VertexContainer& vertices) { return vertices[0]->getData()[0] - 3; };
234  EdgeInterface::UPtr edge2(new EdgeT(eq_constr, false, v1));
235  graph.addEqualityConstraintEdge(std::move(edge2));
236 
237  solver.setPenaltyWeights(100, 100, 100);
238 
239  EXPECT_TRUE(solver.initialize(graph));
240 
241  bool success = solver.solve(graph, true);
242 
243  EXPECT_TRUE(success);
244  EXPECT_NEAR(v1.values()[0], 3.0, 1e-4);
245 }
246 
248 {
249  // Vertices
250  VectorVertex v1(1);
251  v1.values().setOnes();
252  graph.addVertex(&v1);
253 
254  // Edges
256 
257  // create some edges types
258  auto edge_fun = [](const EdgeT::VertexContainer& vertices) { return vertices[0]->getData()[0] - 2; }; // min -> x = 2
259  EdgeInterface::UPtr edge1(new EdgeT(edge_fun, true, v1));
260  graph.addObjectiveEdge(std::move(edge1));
261 
262  auto eq_constr = [](const EdgeT::VertexContainer& vertices) { return -vertices[0]->getData()[0] + 3; }; // x > 3
263  EdgeInterface::UPtr edge2(new EdgeT(eq_constr, false, v1));
264  graph.addInequalityConstraintEdge(std::move(edge2));
265 
266  solver.setPenaltyWeights(100, 100, 100);
267 
268  EXPECT_TRUE(solver.initialize(graph));
269 
270  bool success = solver.solve(graph, true);
271 
272  EXPECT_TRUE(success);
273  EXPECT_NEAR(v1.values()[0], 3.0, 1e-4);
274 }
275 
277 {
278  // Vertices
279  VectorVertex v1(1);
280  v1.values().setOnes();
281 
282  Eigen::VectorXd lb(1);
283  lb[0] = 5;
284  v1.setLowerBounds(lb);
285 
286  graph.addVertex(&v1);
287 
288  // Edges
290 
291  // create some edges types
292  auto edge_fun = [](const EdgeT::VertexContainer& vertices) { return vertices[0]->getData()[0] - 2; };
293 
294  EdgeInterface::UPtr edge(new EdgeT(edge_fun, true, v1));
295  graph.addObjectiveEdge(std::move(edge));
296 
297  solver.setPenaltyWeights(100, 100, 100);
298 
299  EXPECT_TRUE(solver.initialize(graph));
300 
301  bool success = solver.solve(graph, true);
302 
303  EXPECT_TRUE(success);
304  EXPECT_NEAR(v1.values()[0], 5.0, 1e-3);
305 }
306 
308 {
309  // Vertices
310  VectorVertex v1(1);
311  v1.values().setOnes();
312 
313  Eigen::VectorXd ub(1);
314  ub[0] = -1;
315  v1.setUpperBounds(ub);
316 
317  graph.addVertex(&v1);
318 
319  // Edges
321 
322  // create some edges types
323  auto edge_fun = [](const EdgeT::VertexContainer& vertices) { return vertices[0]->getData()[0] - 2; };
324 
325  EdgeInterface::UPtr edge(new EdgeT(edge_fun, true, v1));
326  graph.addObjectiveEdge(std::move(edge));
327 
328  solver.setPenaltyWeights(100, 100, 100);
329 
330  EXPECT_TRUE(solver.initialize(graph));
331 
332  bool success = solver.solve(graph, true);
333 
334  EXPECT_TRUE(success);
335  EXPECT_NEAR(v1.values()[0], -1.0, 1e-3);
336 }
337 
339 {
340  // Add variables
341  VectorVertex x1(1);
342  VectorVertex x2(1);
343 
344  graph.addVertex(&x1);
345  graph.addVertex(&x2);
346 
347  // Create edges for minimizing 0.01 * x1^2 + x2^2 - 100 = f1^2 + f^2 s.t. 2<=x1<=50, -50<=x2<=50, 10*x1-x2>=10
348 
349  // start with f1
350  using Edge1T = EdgeGenericScalarFun<VectorVertex>;
351  auto edge_fun1 = [](const Edge1T::VertexContainer& vertices) {
352  double x1 = vertices[0]->getData()[0];
353  return std::sqrt(0.01) * x1;
354  };
355  EdgeInterface::UPtr edge1(new Edge1T(edge_fun1, true, x1));
356  graph.addObjectiveEdge(std::move(edge1));
357 
358  // now create f2
359  using Edge2T = EdgeGenericScalarFun<VectorVertex>;
360  auto edge_fun2 = [](const Edge2T::VertexContainer& vertices) {
361  double x2 = vertices[0]->getData()[0];
362  return x2;
363  };
364  EdgeInterface::UPtr edge2(new Edge2T(edge_fun2, true, x2));
365  graph.addObjectiveEdge(std::move(edge2));
366 
367  // create bounds on x1 and x2
368  x1.setLowerBound(0, 2);
369  x1.setUpperBound(0, 50);
370  x2.setLowerBound(0, -50);
371  x2.setUpperBound(0, 50);
372 
373  // create linear inequality constraint 10*x1-x2>=10 -> 10*x1-x2-10>=0 -> x2-10*x1+10<=0
375  auto edge_fun3 = [](const Edge3T::VertexContainer& vertices) {
376  double x1 = vertices.at(0)->getData()[0];
377  double x2 = vertices.at(1)->getData()[0];
378  return x2 - 10.0 * x1 + 10.0; // c(x)<=0 convention
379  };
380  EdgeInterface::UPtr edge3(new Edge3T(edge_fun3, false, x1, x2));
381  graph.addInequalityConstraintEdge(std::move(edge3));
382 
383  // feasible start
384  x1.values()[0] = 5;
385  x2.values()[0] = -5;
386 
387  // now solve
388  bool success = solver.solve(graph, true);
389 
390  EXPECT_TRUE(success);
391  EXPECT_NEAR(x1.values()[0], 2.0, 1e-2);
392  EXPECT_NEAR(x2.values()[0], 0.0, 1e-2);
393 
394  // infeasible start
395  x1.values()[0] = -1;
396  x2.values()[0] = -1;
397 
398  solver.setPenaltyWeights(1, 10, 10);
399  solver.setIterations(5000);
400  EXPECT_TRUE(solver.initialize(graph));
401 
402  // now solve
403  success = solver.solve(graph, true);
404 
405  EXPECT_TRUE(success);
406  EXPECT_NEAR(x1.values()[0], 2.0, 1e-2);
407  EXPECT_NEAR(x2.values()[0], 0.0, 1e-2);
408 }
409 
410 TEST_F(TestLevenbergMarquardtDenseHyperGraph, solve_betts_fun_constr_weight_adapt)
411 {
412  // Add variables
413  VectorVertex x1(1);
414  VectorVertex x2(1);
415 
416  graph.addVertex(&x1);
417  graph.addVertex(&x2);
418 
419  // Create edges for minimizing 0.01 * x1^2 + x2^2 - 100 = f1^2 + f^2 s.t. 2<=x1<=50, -50<=x2<=50, 10*x1-x2>=10
420 
421  // start with f1
422  using Edge1T = EdgeGenericScalarFun<VectorVertex>;
423  auto edge_fun1 = [](const Edge1T::VertexContainer& vertices) {
424  double x1 = vertices[0]->getData()[0];
425  return std::sqrt(0.01) * x1;
426  };
427  EdgeInterface::UPtr edge1(new Edge1T(edge_fun1, true, x1));
428  graph.addObjectiveEdge(std::move(edge1));
429 
430  // now create f2
431  using Edge2T = EdgeGenericScalarFun<VectorVertex>;
432  auto edge_fun2 = [](const Edge2T::VertexContainer& vertices) {
433  double x2 = vertices[0]->getData()[0];
434  return x2;
435  };
436  EdgeInterface::UPtr edge2(new Edge2T(edge_fun2, true, x2));
437  graph.addObjectiveEdge(std::move(edge2));
438 
439  // create bounds on x1 and x2
440  x1.setLowerBound(0, 2);
441  x1.setUpperBound(0, 50);
442  x2.setLowerBound(0, -50);
443  x2.setUpperBound(0, 50);
444 
445  // create linear inequality constraint 10*x1-x2>=10 -> 10*x1-x2-10>=0 -> x2-10*x1+10<=0
447  auto edge_fun3 = [](const Edge3T::VertexContainer& vertices) {
448  double x1 = vertices.at(0)->getData()[0];
449  double x2 = vertices.at(1)->getData()[0];
450  return x2 - 10.0 * x1 + 10.0; // c(x)<=0 convention
451  };
452  EdgeInterface::UPtr edge3(new Edge3T(edge_fun3, false, x1, x2));
453  graph.addInequalityConstraintEdge(std::move(edge3));
454 
455  // feasible start
456  x1.values()[0] = 5;
457  x2.values()[0] = -5;
458 
459  // set weight adaptation
460  solver.setPenaltyWeights(2, 2, 2);
461  solver.setWeightAdapation(5, 5, 5, 500, 500, 500);
462  solver.setIterations(5);
463 
464  EXPECT_TRUE(solver.initialize(graph));
465 
466  // now solve
467  bool success;
468  for (int i = 0; i < 5; ++i) success = solver.solve(graph, true, i == 0 ? true : false);
469 
470  EXPECT_TRUE(success);
471  EXPECT_NEAR(x1.values()[0], 2.0, 1e-2);
472  EXPECT_NEAR(x2.values()[0], 0.0, 1e-2);
473 
474  // infeasible start
475  x1.values()[0] = -1;
476  x2.values()[0] = -1;
477 
478  // now solve
479  for (int i = 0; i < 5; ++i) success = solver.solve(graph, true, i == 0 ? true : false);
480 
481  EXPECT_TRUE(success);
482  EXPECT_NEAR(x1.values()[0], 2.0, 1e-2);
483  EXPECT_NEAR(x2.values()[0], 0.0, 1e-2);
484 }
485 
486 TEST_F(TestLevenbergMarquardtDenseHyperGraph, solve_betts_fun_constr_fixed)
487 {
488  // Add variables
489  pfVectorVertex x1(1);
490  VectorVertex x2(1);
491 
492  x1.setFixed(0, true);
493 
494  graph.addVertex(&x1);
495  graph.addVertex(&x2);
496 
497  // Create edges for minimizing 0.01 * x1^2 + x2^2 - 100 = f1^2 + f^2 s.t. 2<=x1<=50, -50<=x2<=50, 10*x1-x2>=10
498 
499  // start with f1
500  using Edge1T = EdgeGenericScalarFun<VectorVertex>;
501  auto edge_fun1 = [](const Edge1T::VertexContainer& vertices) {
502  double x1 = vertices[0]->getData()[0];
503  return std::sqrt(0.01) * x1;
504  };
505  EdgeInterface::UPtr edge1(new Edge1T(edge_fun1, true, x1));
506  graph.addObjectiveEdge(std::move(edge1));
507 
508  // now create f2
509  using Edge2T = EdgeGenericScalarFun<VectorVertex>;
510  auto edge_fun2 = [](const Edge2T::VertexContainer& vertices) {
511  double x2 = vertices[0]->getData()[0];
512  return x2;
513  };
514  EdgeInterface::UPtr edge2(new Edge2T(edge_fun2, true, x2));
515  graph.addObjectiveEdge(std::move(edge2));
516 
517  // create bounds on x1 and x2
518  x1.setLowerBound(0, 2);
519  x1.setUpperBound(0, 50);
520  x2.setLowerBound(0, -50);
521  x2.setUpperBound(0, 50);
522 
523  // create linear inequality constraint 10*x1-x2>=10 -> 10*x1-x2-10>=0 -> x2-10*x1+10<=0
525  auto edge_fun3 = [](const Edge3T::VertexContainer& vertices) {
526  double x1 = vertices.at(0)->getData()[0];
527  double x2 = vertices.at(1)->getData()[0];
528  return x2 - 10.0 * x1 + 10.0; // c(x)<=0 convention
529  };
530  EdgeInterface::UPtr edge3(new Edge3T(edge_fun3, false, x1, x2));
531  graph.addInequalityConstraintEdge(std::move(edge3));
532 
533  // feasible start
534  x1.values()[0] = 2;
535  x2.values()[0] = -5;
536 
537  // now solve
538  bool success = solver.solve(graph, true);
539 
540  EXPECT_TRUE(success);
541  EXPECT_NEAR(x1.values()[0], 2.0, 1e-2);
542  EXPECT_NEAR(x2.values()[0], 0.0, 1e-2);
543 
544  // infeasible start
545  x1.values()[0] = 2;
546  x2.values()[0] = -4;
547 
548  solver.setPenaltyWeights(1, 10, 10);
549  solver.setIterations(100);
550  EXPECT_TRUE(solver.initialize(graph));
551 
552  // now solve
553  success = solver.solve(graph, true);
554 
555  EXPECT_TRUE(success);
556  EXPECT_NEAR(x1.values()[0], 2.0, 1e-2);
557  EXPECT_NEAR(x2.values()[0], 0.0, 1e-2);
558 }
TestLevenbergMarquardtDenseHyperGraph::SetUp
void SetUp() override
Definition: test_levenberg_marquardt_dense_hyper_graph.cpp:65
sqrt
const EIGEN_DEVICE_FUNC SqrtReturnType sqrt() const
Definition: ArrayCwiseUnaryOps.h:152
corbo::VectorVertex::setUpperBounds
void setUpperBounds(const Eigen::Ref< const Eigen::VectorXd > &ub) override
Define upper bounds on the vertex values [getDimension() x 1].
Definition: vector_vertex.h:200
corbo::PartiallyFixedVectorVertex::setFixed
void setFixed(int idx, bool fixed)
Set component with idx (0 <= idx < dimension()) to (un)fixed.
Definition: vector_vertex.h:375
TestLevenbergMarquardtDenseHyperGraph::TestLevenbergMarquardtDenseHyperGraph
TestLevenbergMarquardtDenseHyperGraph()
Definition: test_levenberg_marquardt_dense_hyper_graph.cpp:57
levenberg_marquardt_dense.h
macros.h
console.h
TestLevenbergMarquardtDenseHyperGraph::~TestLevenbergMarquardtDenseHyperGraph
virtual ~TestLevenbergMarquardtDenseHyperGraph()
Definition: test_levenberg_marquardt_dense_hyper_graph.cpp:59
corbo::EdgeGenericScalarFun
Generic edge for functions .
Definition: generic_edge.h:90
utilities.h
value_comparison.h
corbo::VectorVertex::values
const Eigen::VectorXd & values() const
Read-access to the underlying value vector.
Definition: vector_vertex.h:284
TestLevenbergMarquardtDenseHyperGraph::graph
HyperGraph2 graph
Definition: test_levenberg_marquardt_dense_hyper_graph.cpp:79
hyper_graph.h
corbo::VectorVertex::setLowerBound
void setLowerBound(int idx, double lb) override
Define lower bound on a single component of the vertex (0 <= idx < getDimension())
Definition: vector_vertex.h:194
corbo::VectorVertex::getData
const double * getData() const override
Get read-only raw access to the values of the vertex.
Definition: vector_vertex.h:161
corbo::EdgeGenericVectorFun
Generic edge for functions .
Definition: generic_edge.h:172
TestLevenbergMarquardtDenseHyperGraph::solver
LevenbergMarquardtDense solver
Definition: test_levenberg_marquardt_dense_hyper_graph.cpp:81
Eigen::Ref
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:192
TestLevenbergMarquardtDenseHyperGraph
Definition: test_levenberg_marquardt_dense_hyper_graph.cpp:53
generic_edge.h
corbo::VectorVertex::setLowerBounds
void setLowerBounds(const Eigen::Ref< const Eigen::VectorXd > &lb) override
Define lower bounds on the vertex values [getDimension() x 1].
Definition: vector_vertex.h:188
corbo::VectorVertex::setUpperBound
void setUpperBound(int idx, double ub) override
Define upper bound on a single component of the vertex (0 <= idx < getDimension())
Definition: vector_vertex.h:206
TEST_F
TEST_F(TestLevenbergMarquardtDenseHyperGraph, solve_unconstr_1)
Definition: test_levenberg_marquardt_dense_hyper_graph.cpp:84
corbo::VectorVertex
Vertex implementation that stores an Eigen::VectorXd (dynamic dimension)
Definition: vector_vertex.h:73
corbo::EdgeInterface
Generic interface class for edges.
Definition: edge_interface.h:76
corbo::VectorVertex::setFixed
virtual void setFixed(bool fixed)
Set complete vertex to fixed (and hence skip during optimization)
Definition: vector_vertex.h:254
corbo::LevenbergMarquardtDense
Levenberg-Marquardt Solver (Dense matrices version).
Definition: levenberg_marquardt_dense.h:84
corbo::LevenbergMarquardtDense::setIterations
void setIterations(int iterations)
Define the number of solver iterations.
Definition: levenberg_marquardt_dense.h:124
corbo::PartiallyFixedVectorVertex
Vector based vertex with support for partially fixed components.
Definition: vector_vertex.h:298


control_box_rst
Author(s): Christoph Rösmann
autogenerated on Wed Mar 2 2022 00:07:06