GCC Code Coverage Report


Directory: ./
File: src/solver/by-substitution.cc
Date: 2025-05-05 12:19:30
Exec Total Coverage
Lines: 151 181 83.4%
Branches: 153 356 43.0%

Line Branch Exec Source
1 // Copyright (c) 2017, 2018 CNRS
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // 1. Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28
29 #include <boost/serialization/nvp.hpp>
30 #include <hpp/constraints/active-set-differentiable-function.hh>
31 #include <hpp/constraints/macros.hh>
32 #include <hpp/constraints/solver/by-substitution.hh>
33 #include <hpp/constraints/solver/impl/by-substitution.hh>
34 #include <hpp/constraints/solver/impl/hierarchical-iterative.hh>
35 #include <hpp/constraints/svd.hh>
36 #include <hpp/pinocchio/configuration.hh>
37 #include <hpp/pinocchio/liegroup-element.hh>
38 #include <hpp/pinocchio/util.hh>
39 #include <hpp/util/serialization.hh>
40
41 namespace hpp {
42 namespace constraints {
43 namespace solver {
44 namespace lineSearch {
45 template bool Constant::operator()(const BySubstitution& solver,
46 vectorOut_t arg, vectorOut_t darg);
47
48 template bool Backtracking::operator()(const BySubstitution& solver,
49 vectorOut_t arg, vectorOut_t darg);
50
51 template bool FixedSequence::operator()(const BySubstitution& solver,
52 vectorOut_t arg, vectorOut_t darg);
53
54 template bool ErrorNormBased::operator()(const BySubstitution& solver,
55 vectorOut_t arg, vectorOut_t darg);
56 } // namespace lineSearch
57
58 1023 BySubstitution::BySubstitution(const LiegroupSpacePtr_t& configSpace)
59 : HierarchicalIterative(configSpace),
60 1023 explicit_(configSpace),
61
3/6
✓ Branch 2 taken 1023 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1023 times.
✗ Branch 6 not taken.
✓ Branch 12 taken 1023 times.
✗ Branch 13 not taken.
1023 JeExpanded_(configSpace->nv(), configSpace->nv()) {}
62
63 4 BySubstitution::BySubstitution(const BySubstitution& other)
64 : HierarchicalIterative(other),
65 4 explicit_(other.explicit_),
66
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 Je_(other.Je_),
67
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
8 JeExpanded_(other.JeExpanded_) {
68 4 for (NumericalConstraints_t::iterator it(constraints_.begin());
69
2/2
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 4 times.
16 it != constraints_.end(); ++it) {
70 // assert (contains (*it));
71 }
72 4 }
73
74 1049 bool BySubstitution::add(const ImplicitPtr_t& nm, const std::size_t& priority) {
75
2/4
✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1049 times.
1049 if (contains(nm)) {
76 hppDout(error, "Constraint " << nm->functionPtr()->name()
77 << " already in BySubstitution solver."
78 << std::endl);
79 return false;
80 }
81
2/4
✓ Branch 2 taken 1049 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1049 times.
✗ Branch 6 not taken.
1049 ComparisonTypes_t types = nm->comparisonType();
82
83 1049 bool addedAsExplicit = false;
84 1049 ExplicitPtr_t enm(HPP_DYNAMIC_PTR_CAST(Explicit, nm));
85
2/2
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 1023 times.
1049 if (enm) {
86
1/2
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
26 addedAsExplicit = explicitConstraintSet().add(enm) >= 0;
87 26 if (!addedAsExplicit) {
88 hppDout(info, "Could not treat " << enm->explicitFunction()->name()
89 << " as an explicit function.");
90 }
91 }
92
93
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 1023 times.
1049 if (addedAsExplicit) {
94 // If added as explicit, add to the list of constraint of Hierarchical
95 // iterative
96
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 constraints_.push_back(nm);
97 hppDout(info,
98 "Numerical constraint added as explicit function: "
99 << enm->explicitFunction()->name() << "with "
100 << "input conf " << Eigen::RowBlockIndices(enm->inputConf())
101 << "input vel" << Eigen::RowBlockIndices(enm->inputVelocity())
102 << "output conf " << Eigen::RowBlockIndices(enm->outputConf())
103 << "output vel "
104 << Eigen::RowBlockIndices(enm->outputVelocity()));
105
1/2
✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
26 explicitConstraintSetHasChanged();
106 } else
107
1/2
✓ Branch 1 taken 1023 times.
✗ Branch 2 not taken.
1023 HierarchicalIterative::add(nm, priority);
108 hppDout(info, "Constraint has dimension " << dimension());
109
110
2/4
✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1049 times.
1049 assert(contains(nm));
111 1049 return true;
112 1049 }
113
114 29 void BySubstitution::explicitConstraintSetHasChanged() {
115 // set free variables to indices that are not output of the explicit
116 // constraint.
117
2/4
✓ Branch 3 taken 29 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 29 times.
✗ Branch 7 not taken.
29 freeVariables(explicit_.notOutDers().transpose());
118 29 }
119
120 2 segments_t BySubstitution::implicitDof() const {
121 2 const Eigen::MatrixXi& ioDep = explicit_.inOutDependencies();
122 2 const Eigen::VectorXi& derF = explicit_.derFunction();
123
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 ArrayXb adp(activeDerivativeParameters());
124
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 Eigen::VectorXi out(Eigen::VectorXi::Zero(adp.size()));
125
126
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
8 for (size_type i = 0; i < adp.size(); ++i) {
127
3/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 2 times.
6 if (adp(i)) {
128
3/4
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
4 if (derF[i] >= 0) {
129
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
3 out += ioDep.row(derF[i]);
130
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 out(i) = 0;
131 } else
132
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 out(i) += 1;
133 }
134 }
135
3/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
4 return BlockIndex::fromLogicalExpression(out.array().cast<bool>());
136 2 }
137
138 // Note that the jacobian of the implicit constraints have already
139 // been computed by computeValue <true>
140 // The Jacobian of the implicit constraint of priority i is stored in
141 // datas_ [i].jacobian
142 13396 void BySubstitution::updateJacobian(vectorIn_t arg) const {
143
2/2
✓ Branch 2 taken 13214 times.
✓ Branch 3 taken 182 times.
13396 if (explicit_.inDers().nbCols() == 0) return;
144 /* ------
145 / in in u out \
146 | |
147 Je_ = | df |
148 | ---- (qin) 0 |
149 \ dqin /
150 */
151
2/4
✓ Branch 2 taken 182 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 182 times.
✗ Branch 6 not taken.
182 explicit_.jacobian(JeExpanded_, arg);
152
1/2
✓ Branch 2 taken 182 times.
✗ Branch 3 not taken.
182 Je_ = explicit_.jacobianNotOutToOut(JeExpanded_);
153
154 hppDnum(info, "Jacobian of explicit system is" << iendl << setpyformat
155 << pretty_print(Je_));
156
157
2/2
✓ Branch 1 taken 182 times.
✓ Branch 2 taken 182 times.
364 for (std::size_t i = 0; i < stacks_.size(); ++i) {
158 182 Data& d = datas_[i];
159 hppDnum(
160 info,
161 "Jacobian of stack "
162 << i << " before update:" << iendl << pretty_print(d.reducedJ)
163 << iendl << "Jacobian of explicit variable of stack " << i << ":"
164 << iendl
165 << pretty_print(
166 explicit_.outDers().transpose().rview(d.jacobian).eval()));
167
2/4
✓ Branch 2 taken 182 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 182 times.
✗ Branch 6 not taken.
364 d.reducedJ.noalias() += Eigen::MatrixBlocksRef<>(d.activeRowsOfJ.keepRows(),
168 182 explicit_.outDers())
169
1/2
✓ Branch 1 taken 182 times.
✗ Branch 2 not taken.
182 .rview(d.jacobian)
170
1/2
✓ Branch 1 taken 182 times.
✗ Branch 2 not taken.
364 .eval() *
171
2/4
✓ Branch 2 taken 182 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 182 times.
✗ Branch 6 not taken.
546 Je_;
172 hppDnum(info, "Jacobian of stack " << i << " after update:" << iendl
173 << pretty_print(d.reducedJ)
174 << unsetpyformat);
175 }
176 }
177
178 1049 void BySubstitution::computeActiveRowsOfJ(std::size_t iStack) {
179 1049 Data& d = datas_[iStack];
180 const ImplicitConstraintSet::Implicits_t constraints(
181
1/2
✓ Branch 3 taken 1049 times.
✗ Branch 4 not taken.
1049 stacks_[iStack].constraints());
182 1049 std::size_t row = 0;
183
184 /// ADP: Active Derivative Param
185
1/2
✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
1049 Eigen::MatrixXi explicitIOdep = explicit_.inOutDofDependencies();
186
4/8
✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1049 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1049 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 1049 times.
1049 assert((explicitIOdep.array() >= 0).all());
187
188 typedef Eigen::MatrixBlocks<false, false> BlockIndices;
189
190
2/4
✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1049 times.
✗ Branch 5 not taken.
1049 ArrayXb adpF, adpC;
191 1049 BlockIndices::segments_t rows;
192
2/2
✓ Branch 1 taken 1058 times.
✓ Branch 2 taken 1049 times.
2107 for (std::size_t i = 0; i < constraints.size(); ++i) {
193 bool active;
194
195 // Test on the variable left free by the explicit solver.
196 1058 adpF = freeVariables_
197
1/2
✓ Branch 2 taken 1058 times.
✗ Branch 3 not taken.
2116 .rview(constraints[i]
198 1058 ->function()
199 1058 .activeDerivativeParameters()
200
1/2
✓ Branch 1 taken 1058 times.
✗ Branch 2 not taken.
1058 .matrix())
201
1/2
✓ Branch 1 taken 1058 times.
✗ Branch 2 not taken.
1058 .eval()
202
2/4
✓ Branch 1 taken 1058 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1058 times.
✗ Branch 5 not taken.
1058 .array();
203
1/2
✓ Branch 1 taken 1058 times.
✗ Branch 2 not taken.
1058 active = adpF.any();
204
6/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1054 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 1055 times.
1058 if (!active && explicitIOdep.size() > 0) {
205 // Test on the variable constrained by the explicit solver.
206 3 adpC = explicit_.outDers()
207
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 .rview(constraints[i]
208 3 ->function()
209 3 .activeDerivativeParameters()
210
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .matrix())
211
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .eval()
212
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 .array();
213
4/8
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 3 times.
✗ Branch 11 not taken.
3 adpF = (explicitIOdep.transpose() * adpC.cast<int>().matrix())
214
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .array()
215
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
3 .cast<bool>();
216
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 active = adpF.any();
217 }
218
2/2
✓ Branch 0 taken 1056 times.
✓ Branch 1 taken 2 times.
1058 if (active) { // If at least one element of adp is true
219
2/2
✓ Branch 7 taken 1056 times.
✓ Branch 8 taken 1056 times.
2112 for (const segment_t s : constraints[i]->activeRows()) {
220
1/2
✓ Branch 1 taken 1056 times.
✗ Branch 2 not taken.
1056 rows.emplace_back(s.first + row, s.second);
221 }
222 }
223 1058 row += constraints[i]->function().outputDerivativeSize();
224 }
225 d.activeRowsOfJ =
226
2/4
✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1049 times.
✗ Branch 5 not taken.
1049 Eigen::MatrixBlocks<false, false>(rows, freeVariables_.m_rows);
227
1/2
✓ Branch 1 taken 1049 times.
✗ Branch 2 not taken.
1049 d.activeRowsOfJ.updateRows<true, true, true>();
228 1049 }
229
230 void BySubstitution::projectVectorOnKernel(ConfigurationIn_t arg,
231 vectorIn_t darg,
232 vectorOut_t result) const {
233 if (constraints_.empty() || reducedDimension() == 0) {
234 result = darg;
235 return;
236 }
237 computeValue<true>(arg);
238 updateJacobian(arg);
239 getReducedJacobian(reducedJ_);
240
241 svd_.compute(reducedJ_);
242
243 // TODO the output of explicit solver should be set to zero ?
244 dqSmall_ = freeVariables_.rview(darg);
245
246 size_type rank = svd_.rank();
247 vector_t tmp(getV1(svd_, rank).adjoint() * dqSmall_);
248 dqSmall_.noalias() -= getV1(svd_, rank) * tmp;
249
250 // Otherwise two uninitialized values may sum up to NaN
251 result.setZero();
252 freeVariables_.lview(result) = dqSmall_;
253 }
254
255 void BySubstitution::projectOnKernel(ConfigurationIn_t from,
256 ConfigurationIn_t to,
257 ConfigurationOut_t result) {
258 // TODO equivalent
259 if (constraints_.empty()) {
260 result = to;
261 return;
262 }
263 typedef pinocchio::LiegroupElement Lge_t;
264 typedef pinocchio::LiegroupElementConstRef LgeConstRef_t;
265 LgeConstRef_t O(from, configSpace_);
266 LgeConstRef_t M(to, configSpace_);
267 OM_ = M - O;
268
269 projectVectorOnKernel(from, OM_, OP_);
270
271 assert(hpp::pinocchio::checkNormalized(M));
272 Lge_t P(O + OP_);
273 assert(hpp::pinocchio::checkNormalized(P));
274 saturate_->saturate(P.vector(), result, saturation_);
275 }
276
277 2 std::ostream& BySubstitution::print(std::ostream& os) const {
278 2 os << "BySubstitution" << incendl;
279 2 HierarchicalIterative::print(os) << iendl;
280 2 explicit_.print(os) << decindent;
281 2 return os;
282 }
283
284 1504 vector_t BySubstitution::rightHandSideFromConfig(ConfigurationIn_t config) {
285 1504 const size_type top = parent_t::rightHandSideSize();
286 1504 const size_type bot = explicit_.rightHandSideSize();
287
1/2
✓ Branch 1 taken 1504 times.
✗ Branch 2 not taken.
1504 vector_t rhs(top + bot);
288
4/8
✓ Branch 1 taken 1504 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1504 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1504 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1504 times.
✗ Branch 11 not taken.
1504 rhs.head(top) = parent_t::rightHandSideFromConfig(config);
289
4/8
✓ Branch 1 taken 1504 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1504 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1504 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1504 times.
✗ Branch 11 not taken.
1504 rhs.tail(bot) = explicit_.rightHandSideFromInput(config);
290 1504 return rhs;
291 }
292
293 4103 bool BySubstitution::rightHandSideFromConfig(const ImplicitPtr_t& constraint,
294 ConfigurationIn_t config) {
295
4/6
✓ Branch 1 taken 4103 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4103 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2101 times.
✓ Branch 8 taken 2002 times.
4103 if (parent_t::rightHandSideFromConfig(constraint, config)) return true;
296 2002 ExplicitPtr_t exp(HPP_DYNAMIC_PTR_CAST(Explicit, constraint));
297
1/2
✓ Branch 1 taken 2002 times.
✗ Branch 2 not taken.
2002 if (exp) {
298
2/4
✓ Branch 1 taken 2002 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2002 times.
✗ Branch 5 not taken.
2002 return explicit_.rightHandSideFromInput(exp, config);
299 }
300 return false;
301 2002 }
302
303 3103 bool BySubstitution::rightHandSide(const ImplicitPtr_t& constraint,
304 vectorIn_t rhs) {
305
4/6
✓ Branch 1 taken 3103 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3103 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2101 times.
✓ Branch 8 taken 1002 times.
3103 if (parent_t::rightHandSide(constraint, rhs)) return true;
306 1002 ExplicitPtr_t exp(HPP_DYNAMIC_PTR_CAST(Explicit, constraint));
307
1/2
✓ Branch 1 taken 1002 times.
✗ Branch 2 not taken.
1002 if (exp) {
308
2/4
✓ Branch 1 taken 1002 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1002 times.
✗ Branch 5 not taken.
1002 return explicit_.rightHandSide(exp, rhs);
309 }
310 return false;
311 1002 }
312
313 5103 bool BySubstitution::getRightHandSide(const ImplicitPtr_t& constraint,
314 vectorOut_t rhs) const {
315
4/6
✓ Branch 1 taken 5103 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5103 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3101 times.
✓ Branch 7 taken 2002 times.
5103 if (parent_t::getRightHandSide(constraint, rhs)) return true;
316 2002 ExplicitPtr_t exp(HPP_DYNAMIC_PTR_CAST(Explicit, constraint));
317
1/2
✓ Branch 1 taken 2002 times.
✗ Branch 2 not taken.
2002 if (exp) {
318
2/4
✓ Branch 1 taken 2002 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2002 times.
✗ Branch 5 not taken.
2002 return explicit_.getRightHandSide(exp, rhs);
319 }
320 return false;
321 2002 }
322
323 100 void BySubstitution::rightHandSide(vectorIn_t rhs) {
324 100 const size_type top = parent_t::rightHandSideSize();
325 100 const size_type bot = explicit_.rightHandSideSize();
326
2/4
✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 100 times.
✗ Branch 6 not taken.
100 parent_t::rightHandSide(rhs.head(top));
327
2/4
✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 100 times.
✗ Branch 6 not taken.
100 explicit_.rightHandSide(rhs.head(bot));
328 100 }
329
330 400 vector_t BySubstitution::rightHandSide() const {
331 400 const size_type top = parent_t::rightHandSideSize();
332 400 const size_type bot = explicit_.rightHandSideSize();
333
1/2
✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
400 vector_t rhs(top + bot);
334
3/6
✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 400 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 400 times.
✗ Branch 8 not taken.
400 rhs.head(top) = parent_t::rightHandSide();
335
3/6
✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 400 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 400 times.
✗ Branch 8 not taken.
400 rhs.tail(bot) = explicit_.rightHandSide();
336 400 return rhs;
337 }
338
339 1 size_type BySubstitution::rightHandSideSize() const {
340 1 const size_type top = parent_t::rightHandSideSize();
341 1 const size_type bot = explicit_.rightHandSideSize();
342 1 return top + bot;
343 }
344
345 6 bool BySubstitution::isConstraintSatisfied(const ImplicitPtr_t& constraint,
346 vectorIn_t arg, vectorOut_t error,
347 bool& constraintFound) const {
348 6 constraintFound = false;
349 bool satisfied(
350
2/4
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
6 parent_t::isConstraintSatisfied(constraint, arg, error, constraintFound));
351
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
6 if (constraintFound) return satisfied;
352
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
8 return explicit_.isConstraintSatisfied(constraint, arg, error,
353 4 constraintFound);
354 }
355
356 template <class Archive>
357 2 void BySubstitution::load(Archive& ar, const unsigned int version) {
358 using namespace boost::serialization;
359 (void)version;
360 2 LiegroupSpacePtr_t space;
361
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(space);
362
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 explicit_.init(space);
363
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 ar& make_nvp("base", base_object<HierarchicalIterative>(*this));
364 }
365
366 template <class Archive>
367 2 void BySubstitution::save(Archive& ar, const unsigned int version) const {
368 using namespace boost::serialization;
369 (void)version;
370 2 LiegroupSpacePtr_t space(explicit_.configSpace());
371
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 ar& BOOST_SERIALIZATION_NVP(space);
372
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
2 ar& make_nvp("base", base_object<HierarchicalIterative>(*this));
373 }
374
375 HPP_SERIALIZATION_SPLIT_IMPLEMENT(BySubstitution);
376
377 template BySubstitution::Status BySubstitution::impl_solve(
378 vectorOut_t arg, bool optimize, lineSearch::Constant lineSearch) const;
379 template BySubstitution::Status BySubstitution::impl_solve(
380 vectorOut_t arg, bool optimize, lineSearch::Backtracking lineSearch) const;
381 template BySubstitution::Status BySubstitution::impl_solve(
382 vectorOut_t arg, bool optimize, lineSearch::FixedSequence lineSearch) const;
383 template BySubstitution::Status BySubstitution::impl_solve(
384 vectorOut_t arg, bool optimize,
385 lineSearch::ErrorNormBased lineSearch) const;
386 } // namespace solver
387 } // namespace constraints
388 } // namespace hpp
389
390 11 BOOST_CLASS_EXPORT(hpp::constraints::solver::BySubstitution)
391