Directory: | ./ |
---|---|
File: | src/solver/hierarchical-iterative.cc |
Date: | 2025-05-05 12:19:30 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 539 | 578 | 93.3% |
Branches: | 451 | 870 | 51.8% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2017, Joseph Mirabel | ||
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/shared_ptr.hpp> | ||
30 | #include <boost/serialization/vector.hpp> | ||
31 | #include <hpp/constraints/implicit.hh> | ||
32 | #include <hpp/constraints/macros.hh> | ||
33 | #include <hpp/constraints/solver/hierarchical-iterative.hh> | ||
34 | #include <hpp/constraints/solver/impl/hierarchical-iterative.hh> | ||
35 | #include <hpp/constraints/svd.hh> | ||
36 | #include <hpp/pinocchio/device.hh> | ||
37 | #include <hpp/pinocchio/joint-collection.hh> | ||
38 | #include <hpp/pinocchio/liegroup-element.hh> | ||
39 | #include <hpp/pinocchio/serialization.hh> | ||
40 | #include <hpp/pinocchio/util.hh> | ||
41 | #include <hpp/util/debug.hh> | ||
42 | #include <hpp/util/serialization.hh> | ||
43 | #include <hpp/util/timer.hh> | ||
44 | #include <limits> | ||
45 | #include <pinocchio/multibody/model.hpp> | ||
46 | #include <pinocchio/serialization/eigen.hpp> | ||
47 | |||
48 | // #define SVD_THRESHOLD Eigen::NumTraits<value_type>::dummy_precision() | ||
49 | #define SVD_THRESHOLD 1e-8 | ||
50 | |||
51 | namespace hpp { | ||
52 | namespace constraints { | ||
53 | namespace solver { | ||
54 | namespace { | ||
55 | template <bool Superior, bool ComputeJac, typename Derived> | ||
56 | 2618 | void compare(value_type& val, const Eigen::MatrixBase<Derived>& jac, | |
57 | const value_type& thr) { | ||
58 |
2/2✓ Branch 0 taken 410 times.
✓ Branch 1 taken 899 times.
|
2618 | if ((Superior && val < thr) || (!Superior && -thr < val)) { |
59 | if (Superior) | ||
60 | 352 | val -= thr; | |
61 | else | ||
62 | 468 | val += thr; | |
63 | } else { | ||
64 | 1798 | val = 0; | |
65 | if (ComputeJac) | ||
66 | 842 | const_cast<Eigen::MatrixBase<Derived>&>(jac).derived().setZero(); | |
67 | } | ||
68 | 2618 | } | |
69 | |||
70 | template <bool ComputeJac> | ||
71 | 51854 | void applyComparison(const ComparisonTypes_t comparison, | |
72 | const std::vector<std::size_t>& indices, vector_t& value, | ||
73 | matrix_t& jacobian, const value_type& thr) { | ||
74 |
2/2✓ Branch 1 taken 1309 times.
✓ Branch 2 taken 25927 times.
|
54472 | for (std::size_t i = 0; i < indices.size(); ++i) { |
75 | 2618 | const std::size_t j = indices[i]; | |
76 |
2/2✓ Branch 1 taken 523 times.
✓ Branch 2 taken 786 times.
|
2618 | if (comparison[j] == Superior) { |
77 |
2/4✓ Branch 2 taken 523 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 523 times.
✗ Branch 6 not taken.
|
1046 | compare<true, ComputeJac>(value[j], jacobian.row(j), thr); |
78 |
1/2✓ Branch 1 taken 786 times.
✗ Branch 2 not taken.
|
1572 | } else if (comparison[j] == Inferior) { |
79 |
2/4✓ Branch 2 taken 786 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 786 times.
✗ Branch 6 not taken.
|
1572 | compare<false, ComputeJac>(value[j], jacobian.row(j), thr); |
80 | } | ||
81 | } | ||
82 | 51854 | } | |
83 | } // namespace | ||
84 | |||
85 | namespace lineSearch { | ||
86 | template bool Constant::operator()(const HierarchicalIterative& solver, | ||
87 | vectorOut_t arg, vectorOut_t darg); | ||
88 | |||
89 |
2/4✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
|
13 | Backtracking::Backtracking() : c(0.001), tau(0.7), smallAlpha(0.2) {} |
90 | template bool Backtracking::operator()(const HierarchicalIterative& solver, | ||
91 | vectorOut_t arg, vectorOut_t darg); | ||
92 | |||
93 | 2041 | FixedSequence::FixedSequence() : alpha(.2), alphaMax(.95), K(.8) {} | |
94 | template bool FixedSequence::operator()(const HierarchicalIterative& solver, | ||
95 | vectorOut_t arg, vectorOut_t darg); | ||
96 | |||
97 | ✗ | ErrorNormBased::ErrorNormBased(value_type alphaMin, value_type _a, | |
98 | ✗ | value_type _b) | |
99 | ✗ | : C(0.5 + alphaMin / 2), K((1 - alphaMin) / 2), a(_a), b(_b) {} | |
100 | |||
101 | 2 | ErrorNormBased::ErrorNormBased(value_type alphaMin) | |
102 | 2 | : C(0.5 + alphaMin / 2), K((1 - alphaMin) / 2) { | |
103 | static const value_type delta = 0.02; | ||
104 | static const value_type r_half = 1e6; | ||
105 | |||
106 | 2 | a = atanh((delta - 1 + C) / K) / (1 - r_half); | |
107 | 2 | b = -r_half * a; | |
108 | 2 | } | |
109 | |||
110 | template bool ErrorNormBased::operator()(const HierarchicalIterative& solver, | ||
111 | vectorOut_t arg, vectorOut_t darg); | ||
112 | } // namespace lineSearch | ||
113 | |||
114 | namespace saturation { | ||
115 | 39730 | bool Base::saturate(vectorIn_t q, vectorOut_t qSat, | |
116 | Eigen::VectorXi& saturation) { | ||
117 | 39730 | qSat = q; | |
118 | 39730 | saturation.setZero(); | |
119 | 39730 | return false; | |
120 | } | ||
121 | |||
122 | 138010 | bool clamp(const value_type& lb, const value_type& ub, const value_type& v, | |
123 | value_type& vsat, int& s) { | ||
124 |
2/2✓ Branch 0 taken 3527 times.
✓ Branch 1 taken 134483 times.
|
138010 | if (v <= lb) { |
125 | 3527 | vsat = lb; | |
126 | 3527 | s = -1; | |
127 | 3527 | return true; | |
128 |
2/2✓ Branch 0 taken 2790 times.
✓ Branch 1 taken 131693 times.
|
134483 | } else if (v >= ub) { |
129 | 2790 | vsat = ub; | |
130 | 2790 | s = 1; | |
131 | 2790 | return true; | |
132 | } else { | ||
133 | 131693 | vsat = v; | |
134 | 131693 | s = 0; | |
135 | 131693 | return false; | |
136 | } | ||
137 | } | ||
138 | |||
139 | 465 | bool Bounds::saturate(vectorIn_t q, vectorOut_t qSat, | |
140 | Eigen::VectorXi& saturation) { | ||
141 | 465 | bool sat = false; | |
142 |
2/2✓ Branch 1 taken 2388 times.
✓ Branch 2 taken 465 times.
|
2853 | for (size_type i = 0; i < q.size(); ++i) |
143 |
5/8✓ Branch 5 taken 2388 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2388 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 2388 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 250 times.
✓ Branch 14 taken 2138 times.
|
2388 | if (clamp(lb[i], ub[i], q[i], qSat[i], saturation[iq2iv_[i]])) sat = true; |
144 | 465 | return sat; | |
145 | } | ||
146 | |||
147 | 3604 | bool Device::saturate(vectorIn_t q, vectorOut_t qSat, Eigen::VectorXi& sat) { | |
148 | 3604 | bool ret = false; | |
149 | 3604 | const pinocchio::Model& m = device->model(); | |
150 | |||
151 |
2/2✓ Branch 1 taken 113998 times.
✓ Branch 2 taken 3604 times.
|
117602 | for (std::size_t i = 1; i < m.joints.size(); ++i) { |
152 |
1/2✓ Branch 2 taken 113998 times.
✗ Branch 3 not taken.
|
113998 | const size_type nq = m.joints[i].nq(); |
153 |
1/2✓ Branch 2 taken 113998 times.
✗ Branch 3 not taken.
|
113998 | const size_type nv = m.joints[i].nv(); |
154 |
1/2✓ Branch 2 taken 113998 times.
✗ Branch 3 not taken.
|
113998 | const size_type idx_q = m.joints[i].idx_q(); |
155 |
1/2✓ Branch 2 taken 113998 times.
✗ Branch 3 not taken.
|
113998 | const size_type idx_v = m.joints[i].idx_v(); |
156 |
2/2✓ Branch 0 taken 135622 times.
✓ Branch 1 taken 113998 times.
|
249620 | for (size_type j = 0; j < nq; ++j) { |
157 | 135622 | const size_type iq = idx_q + j; | |
158 | 135622 | const size_type iv = idx_v + std::min(j, nv - 1); | |
159 |
5/8✓ Branch 1 taken 135622 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 135622 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 135622 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6067 times.
✓ Branch 10 taken 129555 times.
|
135622 | if (clamp(m.lowerPositionLimit[iq], m.upperPositionLimit[iq], q[iq], |
160 |
3/6✓ Branch 1 taken 135622 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 135622 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 135622 times.
✗ Branch 8 not taken.
|
135622 | qSat[iq], sat[iv])) |
161 | 6067 | ret = true; | |
162 | } | ||
163 | } | ||
164 | |||
165 | 3604 | const hpp::pinocchio::ExtraConfigSpace& ecs = device->extraConfigSpace(); | |
166 | 3604 | const size_type& d = ecs.dimension(); | |
167 | |||
168 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3604 times.
|
3604 | for (size_type k = 0; k < d; ++k) { |
169 | ✗ | const size_type iq = m.nq + k; | |
170 | ✗ | const size_type iv = m.nv + k; | |
171 | ✗ | if (clamp(ecs.lower(k), ecs.upper(k), q[iq], qSat[iq], sat[iv])) ret = true; | |
172 | } | ||
173 | 3604 | return ret; | |
174 | } | ||
175 | } // namespace saturation | ||
176 | |||
177 | typedef std::pair<DifferentiableFunctionPtr_t, size_type> iqIt_t; | ||
178 | typedef std::pair<DifferentiableFunctionPtr_t, std::size_t> priorityIt_t; | ||
179 | |||
180 | 1034 | HierarchicalIterative::HierarchicalIterative( | |
181 | 1034 | const LiegroupSpacePtr_t& configSpace) | |
182 | 1034 | : squaredErrorThreshold_(0), | |
183 | 1034 | inequalityThreshold_(0), | |
184 | 1034 | maxIterations_(0), | |
185 | 1034 | stacks_(), | |
186 | 1034 | configSpace_(configSpace), | |
187 | 1034 | dimension_(0), | |
188 | 1034 | reducedDimension_(0), | |
189 | 1034 | lastIsOptional_(false), | |
190 | 1034 | solveLevelByLevel_(false), | |
191 |
1/2✓ Branch 1 taken 1034 times.
✗ Branch 2 not taken.
|
1034 | freeVariables_(), |
192 |
2/4✓ Branch 1 taken 1034 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1034 times.
✗ Branch 6 not taken.
|
1034 | saturate_(new saturation::Base()), |
193 | 1034 | constraints_(), | |
194 | 1034 | iq_(), | |
195 | 1034 | iv_(), | |
196 | 1034 | priority_(), | |
197 | 1034 | sigma_(0), | |
198 |
1/2✓ Branch 1 taken 1034 times.
✗ Branch 2 not taken.
|
1034 | dq_(), |
199 |
1/2✓ Branch 1 taken 1034 times.
✗ Branch 2 not taken.
|
1034 | dqSmall_(), |
200 |
1/2✓ Branch 1 taken 1034 times.
✗ Branch 2 not taken.
|
1034 | reducedJ_(), |
201 |
1/2✓ Branch 3 taken 1034 times.
✗ Branch 4 not taken.
|
1034 | saturation_(configSpace->nv()), |
202 |
1/2✓ Branch 1 taken 1034 times.
✗ Branch 2 not taken.
|
1034 | reducedSaturation_(), |
203 |
1/2✓ Branch 3 taken 1034 times.
✗ Branch 4 not taken.
|
1034 | qSat_(configSpace_->nq()), |
204 |
1/2✓ Branch 1 taken 1034 times.
✗ Branch 2 not taken.
|
1034 | tmpSat_(), |
205 | 1034 | squaredNorm_(0), | |
206 | 1034 | datas_(), | |
207 |
1/2✓ Branch 1 taken 1034 times.
✗ Branch 2 not taken.
|
1034 | svd_(), |
208 |
1/2✓ Branch 3 taken 1034 times.
✗ Branch 4 not taken.
|
1034 | OM_(configSpace->nv()), |
209 |
1/2✓ Branch 4 taken 1034 times.
✗ Branch 5 not taken.
|
2068 | OP_(configSpace->nv()) { |
210 | // Initialize freeVariables_ to all indices. | ||
211 |
1/2✓ Branch 3 taken 1034 times.
✗ Branch 4 not taken.
|
1034 | freeVariables_.addRow(0, configSpace_->nv()); |
212 | 1034 | } | |
213 | |||
214 | 4 | HierarchicalIterative::HierarchicalIterative(const HierarchicalIterative& other) | |
215 | 4 | : squaredErrorThreshold_(other.squaredErrorThreshold_), | |
216 | 4 | inequalityThreshold_(other.inequalityThreshold_), | |
217 | 4 | maxIterations_(other.maxIterations_), | |
218 | 4 | stacks_(other.stacks_), | |
219 | 4 | configSpace_(other.configSpace_), | |
220 | 4 | dimension_(other.dimension_), | |
221 | 4 | reducedDimension_(other.reducedDimension_), | |
222 | 4 | lastIsOptional_(other.lastIsOptional_), | |
223 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | freeVariables_(other.freeVariables_), |
224 | 4 | saturate_(other.saturate_), | |
225 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | constraints_(other.constraints_.size()), |
226 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | iq_(other.iq_), |
227 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | iv_(other.iv_), |
228 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | priority_(other.priority_), |
229 | 4 | sigma_(other.sigma_), | |
230 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | dq_(other.dq_), |
231 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | dqSmall_(other.dqSmall_), |
232 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | reducedJ_(other.reducedJ_), |
233 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | saturation_(other.saturation_), |
234 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | reducedSaturation_(other.reducedSaturation_), |
235 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | qSat_(other.qSat_), |
236 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | tmpSat_(other.tmpSat_), |
237 | 4 | squaredNorm_(other.squaredNorm_), | |
238 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | datas_(other.datas_), |
239 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | svd_(other.svd_), |
240 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | OM_(other.OM_), |
241 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
8 | OP_(other.OP_) { |
242 |
2/2✓ Branch 1 taken 12 times.
✓ Branch 2 taken 4 times.
|
16 | for (std::size_t i = 0; i < constraints_.size(); ++i) |
243 |
1/2✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
12 | constraints_[i] = other.constraints_[i]->copy(); |
244 | 4 | } | |
245 | |||
246 | 2108 | bool HierarchicalIterative::contains( | |
247 | const ImplicitPtr_t& numericalConstraint) const { | ||
248 |
1/2✓ Branch 3 taken 2108 times.
✗ Branch 4 not taken.
|
2108 | return find_if(constraints_.begin(), constraints_.end(), |
249 | 1159 | [&numericalConstraint](const ImplicitPtr_t& arg) { | |
250 | 1159 | return *arg == *numericalConstraint; | |
251 | 4216 | }) != constraints_.end(); | |
252 | } | ||
253 | |||
254 | 1043 | bool HierarchicalIterative::add(const ImplicitPtr_t& constraint, | |
255 | const std::size_t& priority) { | ||
256 | 1043 | DifferentiableFunctionPtr_t f(constraint->functionPtr()); | |
257 |
1/2✓ Branch 3 taken 1043 times.
✗ Branch 4 not taken.
|
1043 | if (find_if(priority_.begin(), priority_.end(), |
258 | 1064 | [&f](const priorityIt_t& arg) { return *arg.first == *f; }) != | |
259 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1042 times.
|
2086 | priority_.end()) { |
260 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | std::ostringstream oss; |
261 |
3/6✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
|
1 | oss << "Contraint \"" << f->name() << "\" already in solver"; |
262 |
2/4✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
1 | throw std::logic_error(oss.str().c_str()); |
263 | 1 | } | |
264 |
1/2✓ Branch 1 taken 1042 times.
✗ Branch 2 not taken.
|
1042 | priority_[f] = priority; |
265 |
2/4✓ Branch 2 taken 1042 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1042 times.
✗ Branch 6 not taken.
|
1042 | const ComparisonTypes_t comp(constraint->comparisonType()); |
266 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 1042 times.
|
1042 | assert((size_type)comp.size() == f->outputDerivativeSize()); |
267 | 1042 | const std::size_t minSize = priority + 1; | |
268 |
2/2✓ Branch 1 taken 1032 times.
✓ Branch 2 taken 10 times.
|
1042 | if (stacks_.size() < minSize) { |
269 |
2/4✓ Branch 1 taken 1032 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1032 times.
✗ Branch 5 not taken.
|
1032 | stacks_.resize(minSize, ImplicitConstraintSet()); |
270 |
2/4✓ Branch 1 taken 1032 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1032 times.
✗ Branch 5 not taken.
|
1032 | datas_.resize(minSize, Data()); |
271 | } | ||
272 | 1042 | Data& d = datas_[priority]; | |
273 | // Store rank in output vector value | ||
274 |
1/2✓ Branch 5 taken 1042 times.
✗ Branch 6 not taken.
|
1042 | iq_[f] = datas_[priority].output.space()->nq(); |
275 | // Store rank in output vector derivative | ||
276 |
1/2✓ Branch 5 taken 1042 times.
✗ Branch 6 not taken.
|
1042 | iv_[f] = datas_[priority].output.space()->nv(); |
277 | // warning adding constraint to the stack modifies behind the stage | ||
278 | // the dimension of datas_ [priority].output.space (). It should | ||
279 | // therefore be done after the previous lines. | ||
280 |
1/2✓ Branch 2 taken 1042 times.
✗ Branch 3 not taken.
|
1042 | stacks_[priority].add(constraint); |
281 |
2/2✓ Branch 1 taken 10103 times.
✓ Branch 2 taken 1042 times.
|
11145 | for (std::size_t i = 0; i < comp.size(); ++i) { |
282 |
6/6✓ Branch 1 taken 10100 times.
✓ Branch 2 taken 3 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 10095 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 10095 times.
|
10103 | if ((comp[i] == Superior) || (comp[i] == Inferior)) { |
283 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | d.inequalityIndices.push_back(d.comparison.size()); |
284 |
2/2✓ Branch 1 taken 6058 times.
✓ Branch 2 taken 4037 times.
|
10095 | } else if (comp[i] == Equality) { |
285 |
1/2✓ Branch 2 taken 6058 times.
✗ Branch 3 not taken.
|
6058 | d.equalityIndices.addRow(d.comparison.size(), 1); |
286 | } | ||
287 |
1/2✓ Branch 2 taken 10103 times.
✗ Branch 3 not taken.
|
10103 | d.comparison.push_back(comp[i]); |
288 | } | ||
289 |
1/2✓ Branch 1 taken 1042 times.
✗ Branch 2 not taken.
|
1042 | d.equalityIndices.updateRows<true, true, true>(); |
290 |
1/2✓ Branch 1 taken 1042 times.
✗ Branch 2 not taken.
|
1042 | constraints_.push_back(constraint); |
291 |
1/2✓ Branch 1 taken 1042 times.
✗ Branch 2 not taken.
|
1042 | update(); |
292 | |||
293 | 1042 | return true; | |
294 | 1043 | } | |
295 | |||
296 | 1 | void HierarchicalIterative::merge(const HierarchicalIterative& other) { | |
297 | std::size_t priority; | ||
298 | 1 | for (NumericalConstraints_t::const_iterator it(other.constraints_.begin()); | |
299 |
2/2✓ Branch 3 taken 2 times.
✓ Branch 4 taken 1 times.
|
3 | it != other.constraints_.end(); ++it) { |
300 |
3/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
|
2 | if (!this->contains(*it)) { |
301 | 1 | const DifferentiableFunctionPtr_t& f = (*it)->functionPtr(); | |
302 | std::map<DifferentiableFunctionPtr_t, std::size_t>::const_iterator itp( | ||
303 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | std::find_if( |
304 | other.priority_.begin(), other.priority_.end(), | ||
305 | 1 | [&f](const priorityIt_t& arg) { return *arg.first == *f; })); | |
306 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | if (itp == other.priority_.end()) { |
307 | // If priority is not set, constraint is explicit | ||
308 | 1 | priority = 0; | |
309 | } else { | ||
310 | ✗ | priority = itp->second; | |
311 | } | ||
312 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | this->add(*it, priority); |
313 | } | ||
314 | } | ||
315 | 1 | } | |
316 | |||
317 | ✗ | ArrayXb HierarchicalIterative::activeParameters() const { | |
318 | ✗ | ArrayXb ap(ArrayXb::Constant(configSpace_->nq(), false)); | |
319 | ✗ | for (std::size_t i = 0; i < stacks_.size(); ++i) { | |
320 | #ifndef NDEBUG | ||
321 | ✗ | dynamic_cast<const DifferentiableFunctionSet&>(stacks_[i].function()); | |
322 | #endif | ||
323 | const DifferentiableFunctionSet& dfs( | ||
324 | ✗ | dynamic_cast<const DifferentiableFunctionSet&>(stacks_[i].function())); | |
325 | ✗ | ap = ap || dfs.activeParameters(); | |
326 | } | ||
327 | ✗ | return ap; | |
328 | } | ||
329 | |||
330 | 2 | ArrayXb HierarchicalIterative::activeDerivativeParameters() const { | |
331 |
2/4✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
2 | ArrayXb ap(ArrayXb::Constant(configSpace_->nv(), false)); |
332 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
|
4 | for (std::size_t i = 0; i < stacks_.size(); ++i) { |
333 | #ifndef NDEBUG | ||
334 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | dynamic_cast<const DifferentiableFunctionSet&>(stacks_[i].function()); |
335 | #endif | ||
336 | const DifferentiableFunctionSet& dfs( | ||
337 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | dynamic_cast<const DifferentiableFunctionSet&>(stacks_[i].function())); |
338 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | ap = ap || dfs.activeDerivativeParameters(); |
339 | } | ||
340 | 2 | return ap; | |
341 | } | ||
342 | |||
343 | 1071 | void HierarchicalIterative::update() { | |
344 | // Compute reduced size | ||
345 | 1071 | std::size_t reducedSize = freeVariables_.nbIndices(); | |
346 | |||
347 | 1071 | dimension_ = 0; | |
348 | 1071 | reducedDimension_ = 0; | |
349 |
2/2✓ Branch 1 taken 1073 times.
✓ Branch 2 taken 1071 times.
|
2144 | for (std::size_t i = 0; i < stacks_.size(); ++i) { |
350 | 1073 | computeActiveRowsOfJ(i); | |
351 | |||
352 | 1073 | const ImplicitConstraintSet& constraints(stacks_[i]); | |
353 | #ifndef NDEBUG | ||
354 |
1/2✓ Branch 1 taken 1073 times.
✗ Branch 2 not taken.
|
1073 | dynamic_cast<const DifferentiableFunctionSet&>(constraints.function()); |
355 | #endif | ||
356 | const DifferentiableFunctionSet& f( | ||
357 | 1073 | static_cast<const DifferentiableFunctionSet&>(constraints.function())); | |
358 | 1073 | dimension_ += f.outputDerivativeSize(); | |
359 | 1073 | reducedDimension_ += datas_[i].activeRowsOfJ.nbRows(); | |
360 |
1/2✓ Branch 2 taken 1073 times.
✗ Branch 3 not taken.
|
1073 | datas_[i].output = LiegroupElement(f.outputSpace()); |
361 |
1/2✓ Branch 2 taken 1073 times.
✗ Branch 3 not taken.
|
1073 | datas_[i].rightHandSide = LiegroupElement(f.outputSpace()); |
362 | 1073 | datas_[i].rightHandSide.setNeutral(); | |
363 |
1/2✓ Branch 5 taken 1073 times.
✗ Branch 6 not taken.
|
1073 | datas_[i].error.resize(f.outputSpace()->nv()); |
364 | |||
365 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 1073 times.
|
1073 | assert(configSpace_->nv() == f.inputDerivativeSize()); |
366 | 1073 | datas_[i].jacobian.resize(f.outputDerivativeSize(), | |
367 | f.inputDerivativeSize()); | ||
368 | 1073 | datas_[i].jacobian.setZero(); | |
369 | 1073 | datas_[i].reducedJ.resize(datas_[i].activeRowsOfJ.nbRows(), reducedSize); | |
370 | |||
371 | 2146 | datas_[i].svd = SVD_t( | |
372 | f.outputDerivativeSize(), reducedSize, | ||
373 |
2/2✓ Branch 1 taken 1068 times.
✓ Branch 2 taken 5 times.
|
1073 | Eigen::ComputeThinU | (i == stacks_.size() - 1 ? Eigen::ComputeThinV |
374 | 1073 | : Eigen::ComputeFullV)); | |
375 |
1/2✓ Branch 2 taken 1073 times.
✗ Branch 3 not taken.
|
1073 | datas_[i].svd.setThreshold(SVD_THRESHOLD); |
376 | 1073 | datas_[i].PK.resize(reducedSize, reducedSize); | |
377 | |||
378 | 1073 | datas_[i].maxRank = 0; | |
379 | } | ||
380 | |||
381 |
1/2✓ Branch 4 taken 1071 times.
✗ Branch 5 not taken.
|
1071 | dq_ = vector_t::Zero(configSpace_->nv()); |
382 | 1071 | dqSmall_.resize(reducedSize); | |
383 | 1071 | reducedJ_.resize(reducedDimension_, reducedSize); | |
384 | 2142 | svd_ = SVD_t(reducedDimension_, reducedSize, | |
385 | 1071 | Eigen::ComputeThinU | Eigen::ComputeThinV); | |
386 | 1071 | } | |
387 | |||
388 | 24 | void HierarchicalIterative::computeActiveRowsOfJ(std::size_t iStack) { | |
389 | 24 | Data& d = datas_[iStack]; | |
390 | const ImplicitConstraintSet::Implicits_t constraints( | ||
391 |
1/2✓ Branch 3 taken 24 times.
✗ Branch 4 not taken.
|
24 | stacks_[iStack].constraints()); |
392 | 24 | std::size_t offset = 0; | |
393 | |||
394 | typedef Eigen::MatrixBlocks<false, false> BlockIndices; | ||
395 | 24 | BlockIndices::segments_t rows; | |
396 | // Loop over functions of the stack | ||
397 |
2/2✓ Branch 1 taken 34 times.
✓ Branch 2 taken 24 times.
|
58 | for (std::size_t i = 0; i < constraints.size(); ++i) { |
398 | 34 | ArrayXb adp = freeVariables_ | |
399 |
1/2✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
|
68 | .rview(constraints[i] |
400 | 34 | ->function() | |
401 | 34 | .activeDerivativeParameters() | |
402 |
1/2✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
|
34 | .matrix()) |
403 |
2/4✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 34 times.
✗ Branch 5 not taken.
|
34 | .eval(); |
404 |
2/4✓ Branch 1 taken 34 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
✗ Branch 4 not taken.
|
34 | if (adp.any()) // If at least one element of adp is true |
405 |
2/2✓ Branch 7 taken 35 times.
✓ Branch 8 taken 34 times.
|
69 | for (const segment_t s : constraints[i]->activeRows()) { |
406 |
1/2✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
|
35 | rows.emplace_back(s.first + offset, s.second); |
407 | } | ||
408 | 34 | offset += constraints[i]->function().outputDerivativeSize(); | |
409 | 34 | } | |
410 | d.activeRowsOfJ = | ||
411 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
|
24 | Eigen::MatrixBlocks<false, false>(rows, freeVariables_.m_rows); |
412 |
1/2✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
|
24 | d.activeRowsOfJ.updateRows<true, true, true>(); |
413 | 24 | } | |
414 | |||
415 | 1909 | vector_t HierarchicalIterative::rightHandSideFromConfig( | |
416 | ConfigurationIn_t config) { | ||
417 |
2/2✓ Branch 1 taken 1505 times.
✓ Branch 2 taken 1909 times.
|
3414 | for (std::size_t i = 0; i < stacks_.size(); ++i) { |
418 | 1505 | ImplicitConstraintSet& ics = stacks_[i]; | |
419 | 1505 | Data& d = datas_[i]; | |
420 |
2/4✓ Branch 2 taken 1505 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1505 times.
✗ Branch 6 not taken.
|
1505 | ics.rightHandSideFromConfig(config, d.rightHandSide); |
421 | } | ||
422 | 1909 | return rightHandSide(); | |
423 | } | ||
424 | |||
425 | 4103 | bool HierarchicalIterative::rightHandSideFromConfig( | |
426 | const ImplicitPtr_t& constraint, ConfigurationIn_t config) { | ||
427 | 4103 | const DifferentiableFunctionPtr_t& f(constraint->functionPtr()); | |
428 | |||
429 | std::map<DifferentiableFunctionPtr_t, size_type>::iterator iqi( | ||
430 |
1/2✓ Branch 3 taken 4103 times.
✗ Branch 4 not taken.
|
4103 | find_if(iq_.begin(), iq_.end(), |
431 | 4103 | [&f](const iqIt_t& arg) { return *arg.first == *f; })); | |
432 |
2/2✓ Branch 2 taken 2002 times.
✓ Branch 3 taken 2101 times.
|
4103 | if (iqi == iq_.end()) return false; |
433 | 2101 | LiegroupSpacePtr_t space(f->outputSpace()); | |
434 | 2101 | size_type iq = iqi->second; | |
435 | |||
436 | std::map<DifferentiableFunctionPtr_t, std::size_t>::iterator prioi( | ||
437 |
1/2✓ Branch 3 taken 2101 times.
✗ Branch 4 not taken.
|
2101 | find_if(priority_.begin(), priority_.end(), |
438 | 2101 | [&f](const iqIt_t& arg) { return *arg.first == *f; })); | |
439 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 2101 times.
|
2101 | if (prioi == priority_.end()) return false; |
440 | 2101 | std::size_t i = prioi->second; | |
441 | |||
442 | 2101 | size_type nq = space->nq(); | |
443 | 2101 | Data& d = datas_[i]; | |
444 | LiegroupElementRef rhs( | ||
445 |
3/6✓ Branch 3 taken 2101 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2101 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2101 times.
✗ Branch 10 not taken.
|
2101 | space->elementRef(d.rightHandSide.vector().segment(iq, nq))); |
446 |
3/6✓ Branch 2 taken 2101 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2101 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 2101 times.
✗ Branch 9 not taken.
|
2101 | constraint->rightHandSideFromConfig(config, rhs); |
447 | 2101 | return true; | |
448 | 2101 | } | |
449 | |||
450 | 3103 | bool HierarchicalIterative::rightHandSide(const ImplicitPtr_t& constraint, | |
451 | vectorIn_t rightHandSide) { | ||
452 | 3103 | const DifferentiableFunctionPtr_t& f(constraint->functionPtr()); | |
453 | 3103 | LiegroupSpacePtr_t space(f->outputSpace()); | |
454 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 3103 times.
|
3103 | assert(rightHandSide.size() == space->nq()); |
455 | |||
456 | std::map<DifferentiableFunctionPtr_t, size_type>::iterator iqi( | ||
457 |
1/2✓ Branch 3 taken 3103 times.
✗ Branch 4 not taken.
|
3103 | find_if(iq_.begin(), iq_.end(), |
458 | 3106 | [&f](const iqIt_t& arg) { return *arg.first == *f; })); | |
459 |
2/2✓ Branch 2 taken 1002 times.
✓ Branch 3 taken 2101 times.
|
3103 | if (iqi == iq_.end()) return false; |
460 | 2101 | size_type iq = iqi->second; | |
461 | 2101 | size_type nq = space->nq(); | |
462 | |||
463 | std::map<DifferentiableFunctionPtr_t, std::size_t>::iterator prioi( | ||
464 |
1/2✓ Branch 3 taken 2101 times.
✗ Branch 4 not taken.
|
2101 | find_if(priority_.begin(), priority_.end(), |
465 | 2102 | [&f](const iqIt_t& arg) { return *arg.first == *f; })); | |
466 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 2101 times.
|
2101 | if (prioi == priority_.end()) return false; |
467 | 2101 | std::size_t i = prioi->second; | |
468 | |||
469 | 2101 | Data& d = datas_[i]; | |
470 | #ifndef NDEBUG | ||
471 | 2101 | size_type nv = space->nv(); | |
472 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2101 times.
|
2101 | assert(d.error.size() >= nv); |
473 | #endif | ||
474 | pinocchio::LiegroupElementConstRef inRhs( | ||
475 |
2/4✓ Branch 2 taken 2101 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2101 times.
✗ Branch 6 not taken.
|
2101 | space->elementConstRef(rightHandSide)); |
476 | LiegroupElementRef rhs( | ||
477 |
3/6✓ Branch 3 taken 2101 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2101 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2101 times.
✗ Branch 10 not taken.
|
2101 | space->elementRef(d.rightHandSide.vector().segment(iq, nq))); |
478 |
1/2✓ Branch 1 taken 2101 times.
✗ Branch 2 not taken.
|
2101 | rhs = inRhs; |
479 |
3/6✓ Branch 2 taken 2101 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2101 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2101 times.
|
2101 | assert(constraint->checkRightHandSide(inRhs)); |
480 | 2101 | return true; | |
481 | 3103 | } | |
482 | |||
483 | 5103 | bool HierarchicalIterative::getRightHandSide(const ImplicitPtr_t& constraint, | |
484 | vectorOut_t rightHandSide) const { | ||
485 | 5103 | const DifferentiableFunctionPtr_t& f(constraint->functionPtr()); | |
486 | std::map<DifferentiableFunctionPtr_t, std::size_t>::const_iterator itp( | ||
487 |
1/2✓ Branch 3 taken 5103 times.
✗ Branch 4 not taken.
|
5103 | find_if(priority_.begin(), priority_.end(), |
488 | 5106 | [&f](const priorityIt_t& arg) { return *arg.first == *f; })); | |
489 |
2/2✓ Branch 2 taken 2002 times.
✓ Branch 3 taken 3101 times.
|
5103 | if (itp == priority_.end()) { |
490 | 2002 | return false; | |
491 | } | ||
492 | std::map<DifferentiableFunctionPtr_t, size_type>::const_iterator itIq( | ||
493 |
1/2✓ Branch 3 taken 3101 times.
✗ Branch 4 not taken.
|
3101 | find_if(iq_.begin(), iq_.end(), |
494 | 3102 | [&f](const iqIt_t& arg) { return *arg.first == *f; })); | |
495 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 3101 times.
|
3101 | if (itIq == iq_.end()) { |
496 | ✗ | return false; | |
497 | } | ||
498 | 3101 | LiegroupSpacePtr_t space(f->outputSpace()); | |
499 | 3101 | std::size_t i = itp->second; | |
500 | 3101 | size_type iq = itIq->second; | |
501 | 3101 | Data& d = datas_[i]; | |
502 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 3101 times.
|
3101 | assert(rightHandSide.size() == space->nq()); |
503 |
1/2✗ Branch 5 not taken.
✓ Branch 6 taken 3101 times.
|
3101 | assert(d.rightHandSide.space()->nq() >= iq + space->nq()); |
504 |
2/4✓ Branch 4 taken 3101 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3101 times.
✗ Branch 8 not taken.
|
3101 | rightHandSide = d.rightHandSide.vector().segment(iq, space->nq()); |
505 | 3101 | return true; | |
506 | 3101 | } | |
507 | |||
508 | 8 | bool HierarchicalIterative::isConstraintSatisfied( | |
509 | const ImplicitPtr_t& constraint, vectorIn_t arg, vectorOut_t error, | ||
510 | bool& constraintFound) const { | ||
511 | 8 | const DifferentiableFunctionPtr_t& f(constraint->functionPtr()); | |
512 |
1/2✗ Branch 5 not taken.
✓ Branch 6 taken 8 times.
|
8 | assert(error.size() == f->outputSpace()->nv()); |
513 | std::map<DifferentiableFunctionPtr_t, std::size_t>::const_iterator itp( | ||
514 |
1/2✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
8 | find_if(priority_.begin(), priority_.end(), |
515 | 8 | [&f](const priorityIt_t& arg) { return *arg.first == *f; })); | |
516 |
2/2✓ Branch 2 taken 4 times.
✓ Branch 3 taken 4 times.
|
8 | if (itp == priority_.end()) { |
517 | 4 | constraintFound = false; | |
518 | 4 | return false; | |
519 | } | ||
520 | 4 | constraintFound = true; | |
521 | std::map<DifferentiableFunctionPtr_t, size_type>::const_iterator itIq( | ||
522 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | find_if(iq_.begin(), iq_.end(), |
523 | 4 | [&f](const iqIt_t& arg) { return *arg.first == *f; })); | |
524 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 | assert(itIq != iq_.end()); |
525 | std::map<DifferentiableFunctionPtr_t, size_type>::const_iterator itIv( | ||
526 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | find_if(iv_.begin(), iv_.end(), |
527 | 4 | [&f](const iqIt_t& arg) { return *arg.first == *f; })); | |
528 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
4 | assert(itIv != iv_.end()); |
529 | 4 | size_type priority(itp->second); | |
530 | 4 | Data& d = datas_[priority]; | |
531 | // Evaluate constraint function | ||
532 | 4 | size_type iq = itIq->second, nq = f->outputSpace()->nq(); | |
533 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | LiegroupElementRef output(d.output.vector().segment(iq, nq), |
534 |
2/4✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
|
8 | f->outputSpace()); |
535 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
4 | LiegroupElementRef rhs(d.rightHandSide.vector().segment(iq, nq), |
536 |
2/4✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
|
8 | f->outputSpace()); |
537 |
3/6✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
|
4 | f->value(output, arg); |
538 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | error = output - rhs; |
539 |
2/4✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
|
4 | constraint->setInactiveRowsToZero(error); |
540 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | return (error.squaredNorm() < squaredErrorThreshold_); |
541 | 4 | } | |
542 | |||
543 | 100 | void HierarchicalIterative::rightHandSide(vectorIn_t rightHandSide) { | |
544 | 100 | size_type iq = 0, iv = 0; | |
545 |
2/2✓ Branch 1 taken 100 times.
✓ Branch 2 taken 100 times.
|
200 | for (std::size_t i = 0; i < stacks_.size(); ++i) { |
546 | 100 | Data& d = datas_[i]; | |
547 | 100 | LiegroupSpacePtr_t space(d.rightHandSide.space()); | |
548 | 100 | size_type nq = space->nq(); | |
549 | 100 | size_type nv = space->nv(); | |
550 | pinocchio::LiegroupElementConstRef output( | ||
551 |
3/6✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 100 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 100 times.
✗ Branch 9 not taken.
|
100 | space->elementConstRef(rightHandSide.segment(iq, nq))); |
552 | LiegroupElementRef rhs( | ||
553 |
3/6✓ Branch 3 taken 100 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 100 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 100 times.
✗ Branch 10 not taken.
|
100 | space->elementRef(d.rightHandSide.vector().segment(iq, nq))); |
554 | |||
555 | // d.error is used here as an intermediate storage. The value | ||
556 | // computed is not the error | ||
557 |
2/4✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 100 times.
✗ Branch 6 not taken.
|
100 | d.error = output - space->neutral(); // log (rightHandSide) |
558 |
2/2✓ Branch 0 taken 600 times.
✓ Branch 1 taken 100 times.
|
700 | for (size_type k = 0; k < nv; ++k) { |
559 |
1/6✗ Branch 1 not taken.
✓ Branch 2 taken 600 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
|
600 | if (d.comparison[iv + k] != Equality) assert(d.error[k] == 0); |
560 | } | ||
561 |
4/8✓ Branch 1 taken 100 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 100 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 100 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 100 times.
✗ Branch 12 not taken.
|
100 | rhs = space->neutral() + d.error; // exp (d.error) |
562 | 100 | iq += nq; | |
563 | 100 | iv += nv; | |
564 | 100 | } | |
565 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
|
100 | assert(iq == rightHandSide.size()); |
566 | 100 | } | |
567 | |||
568 | ✗ | void HierarchicalIterative::rightHandSideAt(const value_type& s) { | |
569 | ✗ | for (std::size_t i = 0; i < constraints_.size(); ++i) { | |
570 | ✗ | ImplicitPtr_t implicit = constraints_[i]; | |
571 | // If constraint has no right hand side function set, do nothing | ||
572 | ✗ | if ((implicit->parameterSize() != 0) && | |
573 | ✗ | (implicit->rightHandSideFunction())) { | |
574 | ✗ | rightHandSide(implicit, implicit->rightHandSideAt(s)); | |
575 | } | ||
576 | } | ||
577 | } | ||
578 | |||
579 | 2309 | vector_t HierarchicalIterative::rightHandSide() const { | |
580 |
1/2✓ Branch 2 taken 2309 times.
✗ Branch 3 not taken.
|
2309 | vector_t rhs(rightHandSideSize()); |
581 | 2309 | size_type iq = 0; | |
582 |
2/2✓ Branch 1 taken 1905 times.
✓ Branch 2 taken 2309 times.
|
4214 | for (std::size_t i = 0; i < stacks_.size(); ++i) { |
583 | 1905 | const Data& d = datas_[i]; | |
584 | 1905 | size_type nq = d.rightHandSide.space()->nq(); | |
585 | // this does not take the comparison type into account. | ||
586 | // It shouldn't matter as rhs should be zero when comparison type is | ||
587 | // not Equality | ||
588 |
3/6✓ Branch 1 taken 1905 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1905 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1905 times.
✗ Branch 8 not taken.
|
1905 | rhs.segment(iq, nq) = d.rightHandSide.vector(); |
589 | 1905 | iq += nq; | |
590 | } | ||
591 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2309 times.
|
2309 | assert(iq == rhs.size()); |
592 | 2309 | return rhs; | |
593 | } | ||
594 | |||
595 | 4314 | size_type HierarchicalIterative::rightHandSideSize() const { | |
596 | 4314 | size_type rhsSize = 0; | |
597 |
2/2✓ Branch 1 taken 3506 times.
✓ Branch 2 taken 4314 times.
|
7820 | for (std::size_t i = 0; i < stacks_.size(); ++i) |
598 | 3506 | rhsSize += stacks_[i].function().outputSize(); | |
599 | 4314 | return rhsSize; | |
600 | } | ||
601 | |||
602 | template <bool ComputeJac> | ||
603 | 52078 | void HierarchicalIterative::computeValue(vectorIn_t config) const { | |
604 |
2/2✓ Branch 1 taken 25927 times.
✓ Branch 2 taken 26039 times.
|
103932 | for (std::size_t i = 0; i < stacks_.size(); ++i) { |
605 | 51854 | const ImplicitConstraintSet& constraints(stacks_[i]); | |
606 | 51854 | const DifferentiableFunction& f = constraints.function(); | |
607 | 51854 | Data& d = datas_[i]; | |
608 | |||
609 |
2/4✓ Branch 2 taken 25927 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25927 times.
✗ Branch 6 not taken.
|
51854 | f.value(d.output, config); |
610 |
2/4✓ Branch 1 taken 25927 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 25927 times.
|
51854 | assert(hpp::pinocchio::checkNormalized(d.output)); |
611 |
2/4✓ Branch 1 taken 25927 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 25927 times.
|
51854 | assert(hpp::pinocchio::checkNormalized(d.rightHandSide)); |
612 | 51854 | d.error = d.output - d.rightHandSide; | |
613 |
1/2✓ Branch 2 taken 25927 times.
✗ Branch 3 not taken.
|
51854 | constraints.setInactiveRowsToZero(d.error); |
614 | if (ComputeJac) { | ||
615 |
2/4✓ Branch 2 taken 23739 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 23739 times.
✗ Branch 6 not taken.
|
47478 | f.jacobian(d.jacobian, config); |
616 |
3/6✓ Branch 4 taken 23739 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 23739 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 23739 times.
✗ Branch 11 not taken.
|
142434 | d.output.space()->dDifference_dq1<pinocchio::DerivativeTimesInput>( |
617 | 94956 | d.rightHandSide.vector(), d.output.vector(), d.jacobian); | |
618 | } | ||
619 |
1/2✓ Branch 1 taken 25927 times.
✗ Branch 2 not taken.
|
51854 | applyComparison<ComputeJac>(d.comparison, d.inequalityIndices, d.error, |
620 | 51854 | d.jacobian, inequalityThreshold_); | |
621 | |||
622 | // Copy columns that are not reduced | ||
623 |
1/2✓ Branch 2 taken 23739 times.
✗ Branch 3 not taken.
|
47478 | if (ComputeJac) d.reducedJ = d.activeRowsOfJ.rview(d.jacobian); |
624 | } | ||
625 | 52078 | } | |
626 | |||
627 | template void HierarchicalIterative::computeValue<false>( | ||
628 | vectorIn_t config) const; | ||
629 | template void HierarchicalIterative::computeValue<true>( | ||
630 | vectorIn_t config) const; | ||
631 | |||
632 | 22138 | void HierarchicalIterative::computeSaturation(vectorIn_t config) const { | |
633 |
2/4✓ Branch 3 taken 22138 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 22138 times.
✗ Branch 7 not taken.
|
22138 | bool applySaturate = saturate_->saturate(config, qSat_, saturation_); |
634 |
2/2✓ Branch 0 taken 20657 times.
✓ Branch 1 taken 1481 times.
|
22138 | if (!applySaturate) return; |
635 | |||
636 |
1/2✓ Branch 2 taken 1481 times.
✗ Branch 3 not taken.
|
1481 | reducedSaturation_ = freeVariables_.rview(saturation_); |
637 |
10/20✓ Branch 1 taken 1481 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1481 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1481 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1481 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1481 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1481 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1481 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1481 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1481 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✓ Branch 28 taken 1481 times.
|
1481 | assert((reducedSaturation_.array() == -1 || reducedSaturation_.array() == 0 || |
638 | reducedSaturation_.array() == 1) | ||
639 | .all()); | ||
640 | |||
641 |
2/2✓ Branch 1 taken 1492 times.
✓ Branch 2 taken 1481 times.
|
2973 | for (std::size_t i = 0; i < stacks_.size(); ++i) { |
642 | 1492 | Data& d = datas_[i]; | |
643 | |||
644 |
3/6✓ Branch 1 taken 1492 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1492 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1492 times.
✗ Branch 8 not taken.
|
1492 | vector_t error = d.activeRowsOfJ.keepRows().rview(d.error); |
645 | ✗ | tmpSat_ = (reducedSaturation_.cast<value_type>() | |
646 |
3/6✓ Branch 1 taken 1492 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1492 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1492 times.
✗ Branch 8 not taken.
|
1492 | .cwiseProduct(d.reducedJ.transpose() * error) |
647 |
4/8✓ Branch 1 taken 1492 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1492 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1492 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1492 times.
✗ Branch 11 not taken.
|
2984 | .array() < 0); |
648 |
2/2✓ Branch 1 taken 49502 times.
✓ Branch 2 taken 1492 times.
|
50994 | for (size_type j = 0; j < tmpSat_.size(); ++j) |
649 |
5/8✓ Branch 1 taken 49502 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2108 times.
✓ Branch 4 taken 47394 times.
✓ Branch 6 taken 2108 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2108 times.
✗ Branch 10 not taken.
|
49502 | if (tmpSat_[j]) d.reducedJ.col(j).setZero(); |
650 | 1492 | } | |
651 | } | ||
652 | |||
653 | ✗ | void HierarchicalIterative::getValue(vectorOut_t v) const { | |
654 | ✗ | size_type row = 0; | |
655 | ✗ | for (std::size_t i = 0; i < datas_.size(); ++i) { | |
656 | ✗ | const Data& d = datas_[i]; | |
657 | ✗ | v.segment(row, d.output.vector().rows()) = d.output.vector(); | |
658 | ✗ | row += d.output.vector().rows(); | |
659 | } | ||
660 | ✗ | assert(v.rows() == row); | |
661 | } | ||
662 | |||
663 | 6 | void HierarchicalIterative::getReducedJacobian(matrixOut_t J) const { | |
664 | 6 | size_type row = 0; | |
665 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 6 times.
|
12 | for (std::size_t i = 0; i < datas_.size(); ++i) { |
666 | 6 | const Data& d = datas_[i]; | |
667 |
1/2✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
|
6 | J.middleRows(row, d.reducedJ.rows()) = d.reducedJ; |
668 | 6 | row += d.reducedJ.rows(); | |
669 | } | ||
670 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | assert(J.rows() == row); |
671 | 6 | } | |
672 | |||
673 | 26033 | void HierarchicalIterative::computeError() const { | |
674 | const std::size_t end = | ||
675 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 26026 times.
|
26033 | (lastIsOptional_ ? stacks_.size() - 1 : stacks_.size()); |
676 | 26033 | squaredNorm_ = 0; | |
677 |
2/2✓ Branch 0 taken 25914 times.
✓ Branch 1 taken 26033 times.
|
51947 | for (std::size_t i = 0; i < end; ++i) { |
678 | const ImplicitConstraintSet::Implicits_t constraints( | ||
679 |
1/2✓ Branch 3 taken 25914 times.
✗ Branch 4 not taken.
|
25914 | stacks_[i].constraints()); |
680 | 25914 | const Data& d = datas_[i]; | |
681 | 25914 | size_type iv = 0; | |
682 |
2/2✓ Branch 1 taken 26877 times.
✓ Branch 2 taken 25914 times.
|
52791 | for (std::size_t j = 0; j < constraints.size(); ++j) { |
683 | 26877 | size_type nv(constraints[j]->function().outputDerivativeSize()); | |
684 | 26877 | squaredNorm_ = | |
685 |
2/4✓ Branch 1 taken 26877 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 26877 times.
✗ Branch 5 not taken.
|
26877 | std::max(squaredNorm_, d.error.segment(iv, nv).squaredNorm()); |
686 | 26877 | iv += nv; | |
687 | } | ||
688 | 25914 | } | |
689 | 26033 | } | |
690 | |||
691 | 21925 | bool HierarchicalIterative::integrate(vectorIn_t from, vectorIn_t velocity, | |
692 | vectorOut_t result) const { | ||
693 | typedef pinocchio::LiegroupElementRef LgeRef_t; | ||
694 |
1/2✓ Branch 1 taken 21925 times.
✗ Branch 2 not taken.
|
21925 | result = from; |
695 |
1/2✓ Branch 1 taken 21925 times.
✗ Branch 2 not taken.
|
21925 | LgeRef_t M(result, configSpace_); |
696 |
2/4✓ Branch 1 taken 21925 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21925 times.
✗ Branch 5 not taken.
|
21925 | M += velocity; |
697 |
3/6✓ Branch 2 taken 21925 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 21925 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 21925 times.
✗ Branch 9 not taken.
|
43850 | return saturate_->saturate(result, result, saturation_); |
698 | 21925 | } | |
699 | |||
700 | 1392 | void HierarchicalIterative::residualError(vectorOut_t error) const { | |
701 | 1392 | size_type row = 0; | |
702 |
2/2✓ Branch 1 taken 1388 times.
✓ Branch 2 taken 1392 times.
|
2780 | for (std::size_t i = 0; i < datas_.size(); ++i) { |
703 | 1388 | const Data& d = datas_[i]; | |
704 |
1/2✓ Branch 3 taken 1388 times.
✗ Branch 4 not taken.
|
1388 | error.segment(row, d.error.size()) = d.error; |
705 | 1388 | row += d.error.size(); | |
706 | } | ||
707 | 1392 | } | |
708 | |||
709 | 6 | bool HierarchicalIterative::definesSubmanifoldOf( | |
710 | const HierarchicalIterative& solver) const { | ||
711 | 6 | for (NumericalConstraints_t::const_iterator it(solver.constraints().begin()); | |
712 |
2/2✓ Branch 4 taken 8 times.
✓ Branch 5 taken 6 times.
|
14 | it != solver.constraints().end(); ++it) { |
713 | 8 | const DifferentiableFunctionPtr_t& f = (*it)->functionPtr(); | |
714 |
1/2✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
|
8 | if (find_if(constraints_.begin(), constraints_.end(), |
715 | 10 | [&f](const ImplicitPtr_t& arg) { | |
716 | 10 | return arg->function() == *f; | |
717 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
16 | }) == constraints_.end()) |
718 | ✗ | return false; | |
719 | } | ||
720 | 6 | return true; | |
721 | } | ||
722 | |||
723 | 22138 | void HierarchicalIterative::computeDescentDirection() const { | |
724 | 22138 | sigma_ = std::numeric_limits<value_type>::max(); | |
725 | |||
726 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 22138 times.
|
22138 | if (stacks_.empty()) { |
727 | ✗ | dq_.setZero(); | |
728 | ✗ | return; | |
729 | } | ||
730 |
1/2✓ Branch 1 taken 22138 times.
✗ Branch 2 not taken.
|
22138 | vector_t err; |
731 |
2/2✓ Branch 1 taken 21996 times.
✓ Branch 2 taken 142 times.
|
22138 | if (stacks_.size() == 1) { // one level only |
732 | 21996 | Data& d = datas_[0]; | |
733 |
1/2✓ Branch 1 taken 21996 times.
✗ Branch 2 not taken.
|
21996 | d.svd.compute(d.reducedJ); |
734 | HPP_DEBUG_SVDCHECK(d.svd); | ||
735 | // TODO Eigen::JacobiSVD does a dynamic allocation here. | ||
736 |
4/8✓ Branch 1 taken 21996 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21996 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 21996 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 21996 times.
✗ Branch 11 not taken.
|
21996 | err = d.activeRowsOfJ.keepRows().rview(-d.error); |
737 |
2/4✓ Branch 1 taken 21996 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21996 times.
✗ Branch 5 not taken.
|
21996 | dqSmall_ = d.svd.solve(err); |
738 |
1/2✓ Branch 1 taken 21996 times.
✗ Branch 2 not taken.
|
21996 | d.maxRank = std::max(d.maxRank, d.svd.rank()); |
739 |
2/2✓ Branch 0 taken 21995 times.
✓ Branch 1 taken 1 times.
|
21996 | if (d.maxRank > 0) |
740 |
2/4✓ Branch 1 taken 21995 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21995 times.
✗ Branch 5 not taken.
|
21995 | sigma_ = std::min(sigma_, d.svd.singularValues()[d.maxRank - 1]); |
741 | } else { | ||
742 | // dq = dQ_0 + P_0 * v_1 | ||
743 | // f_1(q+dq) = f_1(q) + J_1 * dQ_0 + M_1 * v_1 | ||
744 | // M_1 = J_1 * P_0 | ||
745 | // v_1 = M+_1 * (-f_1(q) - J_1 * dQ_1) + K_1 * v_2 | ||
746 | // dq = dQ_0 + P_0 * M+_1 * (-f_1(q) - J_1 * dQ_1) + P_0 * K_1 * v_2 | ||
747 | // = dQ_1 + P_1 * b_2 | ||
748 | // | ||
749 | // dQ_1 = dQ_0 + P_0 * M+_1 * (-f_1(q) - J_1 * dQ_1) | ||
750 | // P_1 = P_0 * K_1 | ||
751 | 142 | matrix_t* projector = NULL; | |
752 |
1/2✓ Branch 1 taken 284 times.
✗ Branch 2 not taken.
|
284 | for (std::size_t i = 0; i < stacks_.size(); ++i) { |
753 | 284 | Data& d = datas_[i]; | |
754 | |||
755 | // TODO: handle case where this is the first element of the stack and it | ||
756 | // has no functions | ||
757 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 284 times.
|
284 | if (d.reducedJ.rows() == 0) continue; |
758 | /// projector is of size numberDof | ||
759 | 284 | bool first = (i == 0); | |
760 | 284 | bool last = (i == stacks_.size() - 1); | |
761 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 142 times.
|
284 | if (first) { |
762 |
4/8✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 142 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 142 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 142 times.
✗ Branch 11 not taken.
|
142 | err = d.activeRowsOfJ.keepRows().rview(-d.error); |
763 | // dq should be zero and projector should be identity | ||
764 |
1/2✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
|
142 | d.svd.compute(d.reducedJ); |
765 | HPP_DEBUG_SVDCHECK(d.svd); | ||
766 | // TODO Eigen::JacobiSVD does a dynamic allocation here. | ||
767 |
2/4✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 142 times.
✗ Branch 5 not taken.
|
142 | dqSmall_ = d.svd.solve(err); |
768 | } else { | ||
769 |
4/8✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 142 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 142 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 142 times.
✗ Branch 11 not taken.
|
142 | err = d.activeRowsOfJ.keepRows().rview(-d.error); |
770 |
3/6✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 142 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 142 times.
✗ Branch 8 not taken.
|
142 | err.noalias() -= d.reducedJ * dqSmall_; |
771 | |||
772 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 142 times.
|
142 | if (projector == NULL) { |
773 | ✗ | d.svd.compute(d.reducedJ); | |
774 | // TODO Eigen::JacobiSVD does a dynamic allocation here. | ||
775 | ✗ | dqSmall_ += d.svd.solve(err); | |
776 | } else { | ||
777 |
3/6✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 142 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 142 times.
✗ Branch 8 not taken.
|
142 | d.svd.compute(d.reducedJ * *projector); |
778 | // TODO Eigen::JacobiSVD does a dynamic allocation here. | ||
779 |
3/6✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 142 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 142 times.
✗ Branch 8 not taken.
|
142 | dqSmall_ += *projector * d.svd.solve(err); |
780 | } | ||
781 | HPP_DEBUG_SVDCHECK(d.svd); | ||
782 | } | ||
783 | // Update sigma | ||
784 |
1/2✓ Branch 1 taken 284 times.
✗ Branch 2 not taken.
|
284 | const size_type rank = d.svd.rank(); |
785 | 284 | d.maxRank = std::max(d.maxRank, rank); | |
786 |
2/2✓ Branch 0 taken 282 times.
✓ Branch 1 taken 2 times.
|
284 | if (d.maxRank > 0) |
787 |
2/4✓ Branch 1 taken 282 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 282 times.
✗ Branch 5 not taken.
|
282 | sigma_ = std::min(sigma_, d.svd.singularValues()[d.maxRank - 1]); |
788 |
2/8✗ Branch 0 not taken.
✓ Branch 1 taken 284 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 284 times.
|
284 | if (solveLevelByLevel_ && err.squaredNorm() > squaredErrorThreshold_) |
789 | 142 | break; | |
790 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 142 times.
|
284 | if (last) break; // No need to compute projector for next step. |
791 | |||
792 |
2/4✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 142 times.
|
142 | if (d.svd.matrixV().cols() == rank) break; // The kernel is { 0 } |
793 | /// compute projector for next step. | ||
794 |
1/2✓ Branch 0 taken 142 times.
✗ Branch 1 not taken.
|
142 | if (projector == NULL) |
795 |
3/6✓ Branch 1 taken 142 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 142 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 142 times.
✗ Branch 8 not taken.
|
142 | d.PK.noalias() = getV2<SVD_t>(d.svd, rank); |
796 | else | ||
797 | ✗ | d.PK.noalias() = *projector * getV2<SVD_t>(d.svd, rank); | |
798 | 142 | projector = &d.PK; | |
799 | } | ||
800 | } | ||
801 |
1/2✓ Branch 1 taken 22138 times.
✗ Branch 2 not taken.
|
22138 | expandDqSmall(); |
802 | 22138 | } | |
803 | |||
804 | 22138 | void HierarchicalIterative::expandDqSmall() const { | |
805 | 44276 | Eigen::MatrixBlockView<vector_t, Eigen::Dynamic, 1, false, true>( | |
806 |
1/2✓ Branch 4 taken 22138 times.
✗ Branch 5 not taken.
|
22138 | dq_, freeVariables_.nbIndices(), freeVariables_.indices()) = dqSmall_; |
807 | 22138 | } | |
808 | |||
809 | 3 | std::ostream& HierarchicalIterative::print(std::ostream& os) const { | |
810 | 3 | os << "HierarchicalIterative, " << stacks_.size() << " level." << iendl | |
811 | 3 | << "max iter: " << maxIterations() | |
812 | 3 | << ", error threshold: " << errorThreshold() << iendl << "dimension " | |
813 | 3 | << dimension() << iendl << "reduced dimension " << reducedDimension() | |
814 | 3 | << iendl << "free variables: " << freeVariables_ << incindent; | |
815 | const std::size_t end = | ||
816 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
|
3 | (lastIsOptional_ ? stacks_.size() - 1 : stacks_.size()); |
817 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
|
6 | for (std::size_t i = 0; i < stacks_.size(); ++i) { |
818 | const ImplicitConstraintSet::Implicits_t constraints( | ||
819 |
1/2✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
3 | stacks_[i].constraints()); |
820 | 3 | const Data& d = datas_[i]; | |
821 |
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 | os << iendl << "Level " << i; |
822 |
1/6✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
3 | if (lastIsOptional_ && i == end) os << " (optional)"; |
823 |
4/8✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
|
3 | os << ": Stack of " << constraints.size() << " functions" << incindent; |
824 | 3 | size_type rv = 0, rq = 0; | |
825 |
2/2✓ Branch 1 taken 5 times.
✓ Branch 2 taken 3 times.
|
8 | for (std::size_t j = 0; j < constraints.size(); ++j) { |
826 | 5 | const DifferentiableFunctionPtr_t& f(constraints[j]->functionPtr()); | |
827 |
6/12✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 5 times.
✗ Branch 14 not taken.
✓ Branch 18 taken 5 times.
✗ Branch 19 not taken.
|
5 | os << iendl << j << ": [" << rv << ", " << f->outputDerivativeSize() |
828 |
5/10✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 5 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 5 times.
✗ Branch 15 not taken.
|
5 | << "]," << incindent << *f << iendl << "Rhs: " |
829 |
4/8✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 5 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 5 times.
✗ Branch 13 not taken.
|
5 | << condensed(d.rightHandSide.vector().segment(rq, f->outputSize())) |
830 |
4/8✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 10 taken 5 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 5 times.
✗ Branch 14 not taken.
|
5 | << iendl << "active rows: " << condensed(constraints[j]->activeRows()) |
831 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | << decindent; |
832 | 5 | rv += f->outputDerivativeSize(); | |
833 | 5 | rq += f->outputSize(); | |
834 | } | ||
835 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | os << decendl; |
836 |
2/4✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
|
3 | os << "Equality idx: " << d.equalityIndices; |
837 |
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 | os << iendl << "Active rows: " << d.activeRowsOfJ; |
838 | 3 | } | |
839 | 3 | return os << decindent; | |
840 | } | ||
841 | |||
842 | template HierarchicalIterative::Status HierarchicalIterative::solve( | ||
843 | vectorOut_t arg, lineSearch::Constant lineSearch) const; | ||
844 | template HierarchicalIterative::Status HierarchicalIterative::solve( | ||
845 | vectorOut_t arg, lineSearch::Backtracking lineSearch) const; | ||
846 | template HierarchicalIterative::Status HierarchicalIterative::solve( | ||
847 | vectorOut_t arg, lineSearch::FixedSequence lineSearch) const; | ||
848 | template HierarchicalIterative::Status HierarchicalIterative::solve( | ||
849 | vectorOut_t arg, lineSearch::ErrorNormBased lineSearch) const; | ||
850 | |||
851 | template <class Archive> | ||
852 | 2 | void HierarchicalIterative::load(Archive& ar, const unsigned int version) { | |
853 | (void)version; | ||
854 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(squaredErrorThreshold_); |
855 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(inequalityThreshold_); |
856 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(maxIterations_); |
857 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(configSpace_); |
858 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(lastIsOptional_); |
859 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(saturate_); |
860 | |||
861 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | saturation_.resize(configSpace_->nq()); |
862 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | qSat_.resize(configSpace_->nq()); |
863 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | OM_.resize(configSpace_->nv()); |
864 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | OP_.resize(configSpace_->nv()); |
865 | // Initialize freeVariables_ to all indices. | ||
866 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | freeVariables_.addRow(0, configSpace_->nv()); |
867 | |||
868 | 2 | NumericalConstraints_t constraints; | |
869 | 2 | std::vector<std::size_t> priorities; | |
870 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& boost::serialization::make_nvp("constraints_", constraints); |
871 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(priorities); |
872 | |||
873 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
|
8 | for (std::size_t i = 0; i < constraints.size(); ++i) |
874 |
1/2✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
6 | add(constraints[i], priorities[i]); |
875 | // TODO load the right hand side. | ||
876 | } | ||
877 | |||
878 | template <class Archive> | ||
879 | 2 | void HierarchicalIterative::save(Archive& ar, | |
880 | const unsigned int version) const { | ||
881 | (void)version; | ||
882 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(squaredErrorThreshold_); |
883 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(inequalityThreshold_); |
884 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(maxIterations_); |
885 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(configSpace_); |
886 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(lastIsOptional_); |
887 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(saturate_); |
888 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(constraints_); |
889 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | std::vector<std::size_t> priorities(constraints_.size()); |
890 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
|
8 | for (std::size_t i = 0; i < constraints_.size(); ++i) { |
891 | 6 | const DifferentiableFunctionPtr_t& f = constraints_[i]->functionPtr(); | |
892 | std::map<DifferentiableFunctionPtr_t, std::size_t>::const_iterator c( | ||
893 |
1/2✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
|
6 | find_if(priority_.begin(), priority_.end(), |
894 | 5 | [&f](const priorityIt_t& arg) { return *arg.first == *f; })); | |
895 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2 times.
|
6 | if (c == priority_.end()) |
896 | 2 | priorities[i] = 0; | |
897 | else | ||
898 | 4 | priorities[i] = c->second; | |
899 | } | ||
900 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | ar& BOOST_SERIALIZATION_NVP(priorities); |
901 | // TODO save the right hand side. | ||
902 | } | ||
903 | |||
904 | HPP_SERIALIZATION_SPLIT_IMPLEMENT(HierarchicalIterative); | ||
905 | } // namespace solver | ||
906 | } // namespace constraints | ||
907 | } // namespace hpp | ||
908 | |||
909 | 12 | BOOST_CLASS_EXPORT(hpp::constraints::solver::saturation::Bounds) | |
910 | 12 | BOOST_CLASS_EXPORT(hpp::constraints::solver::saturation::Device) | |
911 | |||
912 | namespace boost { | ||
913 | namespace serialization { | ||
914 | using namespace hpp::constraints::solver; | ||
915 | |||
916 | template <class Archive> | ||
917 | 4 | void serialize(Archive&, saturation::Base&, const unsigned int) {} | |
918 | template <class Archive> | ||
919 | 4 | void serialize(Archive& ar, saturation::Device& o, const unsigned int version) { | |
920 | (void)version; | ||
921 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | ar& make_nvp("base", base_object<saturation::Base>(o)); |
922 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | ar& make_nvp("device", o.device); |
923 | } | ||
924 | template <class Archive> | ||
925 | ✗ | void serialize(Archive& ar, saturation::Bounds& o, const unsigned int version) { | |
926 | (void)version; | ||
927 | ✗ | ar& make_nvp("base", base_object<saturation::Base>(o)); | |
928 | ✗ | hpp::serialization::remove_duplicate::serialize_vector(ar, "lb", o.lb, | |
929 | version); | ||
930 | ✗ | hpp::serialization::remove_duplicate::serialize_vector(ar, "ub", o.ub, | |
931 | version); | ||
932 | } | ||
933 | } // namespace serialization | ||
934 | } // namespace boost | ||
935 |