| 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 |