Line |
Branch |
Exec |
Source |
1 |
|
|
// Copyright (c) 2014, LAAS-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 "hpp/manipulation/graph/statistics.hh" |
30 |
|
|
|
31 |
|
|
#include "hpp/manipulation/constraint-set.hh" |
32 |
|
|
|
33 |
|
|
namespace hpp { |
34 |
|
|
namespace manipulation { |
35 |
|
|
namespace graph { |
36 |
|
✗ |
LeafBin::LeafBin(const vector_t& v, value_type* thr) |
37 |
|
✗ |
: value_(v), nodes_(), thr_(thr) {} |
38 |
|
|
|
39 |
|
✗ |
void LeafBin::push_back(const RoadmapNodePtr_t& n) { nodes_.push_back(n); } |
40 |
|
|
|
41 |
|
✗ |
bool LeafBin::operator<(const LeafBin& rhs) const { |
42 |
|
✗ |
const vector_t& v = rhs.value(); |
43 |
|
✗ |
assert(value_.size() == v.size()); |
44 |
|
✗ |
for (int p = 0; p < value_.size(); p++) { |
45 |
|
✗ |
if (std::abs(value_[p] - v[p]) >= *thr_) return value_[p] < v[p]; |
46 |
|
|
} |
47 |
|
✗ |
return false; |
48 |
|
|
} |
49 |
|
|
|
50 |
|
✗ |
bool LeafBin::operator==(const LeafBin& rhs) const { |
51 |
|
✗ |
const vector_t& v = rhs.value(); |
52 |
|
✗ |
assert(value_.size() == v.size()); |
53 |
|
✗ |
for (int p = 0; p < value_.size(); p++) { |
54 |
|
✗ |
if (std::abs(value_[p] - v[p]) >= *thr_) return false; |
55 |
|
|
} |
56 |
|
✗ |
return true; |
57 |
|
|
} |
58 |
|
|
|
59 |
|
✗ |
const vector_t& LeafBin::value() const { return value_; } |
60 |
|
|
|
61 |
|
✗ |
std::ostream& LeafBin::print(std::ostream& os) const { |
62 |
|
✗ |
Parent::print(os) << " ("; |
63 |
|
|
/// Sort by connected component. |
64 |
|
|
typedef std::list<RoadmapNodes_t> NodesList_t; |
65 |
|
✗ |
NodesList_t l; |
66 |
|
|
bool found; |
67 |
|
✗ |
for (RoadmapNodes_t::const_iterator itn = nodes_.begin(); itn != nodes_.end(); |
68 |
|
✗ |
++itn) { |
69 |
|
✗ |
found = false; |
70 |
|
✗ |
for (NodesList_t::iterator itc = l.begin(); itc != l.end(); ++itc) { |
71 |
|
✗ |
if ((*itn)->connectedComponent() == itc->front()->connectedComponent()) { |
72 |
|
✗ |
itc->push_back(*itn); |
73 |
|
✗ |
found = true; |
74 |
|
✗ |
break; |
75 |
|
|
} |
76 |
|
|
} |
77 |
|
✗ |
if (!found) { |
78 |
|
✗ |
l.push_back(RoadmapNodes_t(1, *itn)); |
79 |
|
|
} |
80 |
|
|
} |
81 |
|
✗ |
for (NodesList_t::iterator itc = l.begin(); itc != l.end(); ++itc) |
82 |
|
✗ |
os << itc->front()->connectedComponent() << " - " << itc->size() << ", "; |
83 |
|
✗ |
return os << ")."; |
84 |
|
|
} |
85 |
|
|
|
86 |
|
✗ |
std::ostream& LeafBin::printValue(std::ostream& os) const { |
87 |
|
✗ |
os << "LeafBin ("; |
88 |
|
✗ |
size_t s = value_.size(); |
89 |
|
✗ |
if (s != 0) { |
90 |
|
✗ |
for (size_t i = 0; i < s - 1; i++) os << value_[i] << "; "; |
91 |
|
✗ |
os << value_[s - 1]; |
92 |
|
|
} |
93 |
|
✗ |
os << ")"; |
94 |
|
✗ |
return os; |
95 |
|
|
} |
96 |
|
|
|
97 |
|
✗ |
NodeBin::NodeBin(const StatePtr_t& n) : state_(n), roadmapNodes_() {} |
98 |
|
|
|
99 |
|
✗ |
void NodeBin::push_back(const RoadmapNodePtr_t& n) { |
100 |
|
✗ |
roadmapNodes_.push_back(n); |
101 |
|
|
} |
102 |
|
|
|
103 |
|
✗ |
bool NodeBin::operator<(const NodeBin& rhs) const { |
104 |
|
✗ |
return state()->id() < rhs.state()->id(); |
105 |
|
|
} |
106 |
|
|
|
107 |
|
✗ |
bool NodeBin::operator==(const NodeBin& rhs) const { |
108 |
|
✗ |
return state() == rhs.state(); |
109 |
|
|
} |
110 |
|
|
|
111 |
|
✗ |
const StatePtr_t& NodeBin::state() const { return state_; } |
112 |
|
|
|
113 |
|
✗ |
std::ostream& NodeBin::print(std::ostream& os) const { |
114 |
|
✗ |
Parent::print(os) << " ("; |
115 |
|
|
/// Sort by connected component. |
116 |
|
|
typedef std::list<RoadmapNodes_t> NodesList_t; |
117 |
|
✗ |
NodesList_t l; |
118 |
|
|
bool found; |
119 |
|
✗ |
for (RoadmapNodes_t::const_iterator itn = roadmapNodes_.begin(); |
120 |
|
✗ |
itn != roadmapNodes_.end(); ++itn) { |
121 |
|
✗ |
found = false; |
122 |
|
✗ |
for (NodesList_t::iterator itc = l.begin(); itc != l.end(); ++itc) { |
123 |
|
✗ |
if ((*itn)->connectedComponent() == itc->front()->connectedComponent()) { |
124 |
|
✗ |
itc->push_back(*itn); |
125 |
|
✗ |
found = true; |
126 |
|
✗ |
break; |
127 |
|
|
} |
128 |
|
|
} |
129 |
|
✗ |
if (!found) { |
130 |
|
✗ |
l.push_back(RoadmapNodes_t(1, *itn)); |
131 |
|
|
} |
132 |
|
|
} |
133 |
|
✗ |
for (NodesList_t::iterator itc = l.begin(); itc != l.end(); ++itc) |
134 |
|
✗ |
os << itc->front()->connectedComponent() << " - " << itc->size() << ", "; |
135 |
|
✗ |
return os << ")."; |
136 |
|
|
} |
137 |
|
|
|
138 |
|
✗ |
std::ostream& NodeBin::printValue(std::ostream& os) const { |
139 |
|
✗ |
return os << "NodeBin (" << state()->name() << ")"; |
140 |
|
|
} |
141 |
|
|
|
142 |
|
✗ |
LeafHistogramPtr_t LeafHistogram::create(const Foliation f) { |
143 |
|
✗ |
return LeafHistogramPtr_t(new LeafHistogram(f)); |
144 |
|
|
} |
145 |
|
|
|
146 |
|
✗ |
LeafHistogram::LeafHistogram(const Foliation f) : f_(f), threshold_(0) { |
147 |
|
✗ |
ConfigProjectorPtr_t p = f_.parametrizer()->configProjector(); |
148 |
|
✗ |
if (p) { |
149 |
|
✗ |
if (p->rightHandSide().size() > 0) |
150 |
|
✗ |
threshold_ = |
151 |
|
✗ |
p->errorThreshold() / sqrt((double)p->rightHandSide().size()); |
152 |
|
|
} |
153 |
|
|
} |
154 |
|
|
|
155 |
|
✗ |
void LeafHistogram::add(const RoadmapNodePtr_t& n) { |
156 |
|
✗ |
if (!f_.contains(n->configuration())) return; |
157 |
|
✗ |
iterator it = insert(LeafBin(f_.parameter(n->configuration()), &threshold_)); |
158 |
|
✗ |
it->push_back(n); |
159 |
|
✗ |
if (numberOfObservations() % 10 == 0) { |
160 |
|
|
hppDout(info, *this); |
161 |
|
|
} |
162 |
|
|
} |
163 |
|
|
|
164 |
|
✗ |
std::ostream& LeafHistogram::print(std::ostream& os) const { |
165 |
|
✗ |
os << "Leaf Histogram of foliation " << f_.condition()->name() << std::endl; |
166 |
|
✗ |
return Parent::print(os); |
167 |
|
|
} |
168 |
|
|
|
169 |
|
✗ |
HistogramPtr_t LeafHistogram::clone() const { |
170 |
|
✗ |
return HistogramPtr_t(new LeafHistogram(f_)); |
171 |
|
|
} |
172 |
|
|
|
173 |
|
2 |
StateHistogram::StateHistogram(const graph::GraphPtr_t& graph) |
174 |
|
2 |
: graph_(graph) {} |
175 |
|
|
|
176 |
|
✗ |
void StateHistogram::add(const RoadmapNodePtr_t& n) { |
177 |
|
✗ |
iterator it = insert(NodeBin(constraintGraph()->getState(n))); |
178 |
|
✗ |
it->push_back(n); |
179 |
|
✗ |
if (numberOfObservations() % 10 == 0) { |
180 |
|
|
hppDout(info, *this); |
181 |
|
|
} |
182 |
|
|
} |
183 |
|
|
|
184 |
|
✗ |
std::ostream& StateHistogram::print(std::ostream& os) const { |
185 |
|
✗ |
os << "Graph State Histogram contains: " << std::endl; |
186 |
|
✗ |
return Parent::print(os); |
187 |
|
|
} |
188 |
|
|
|
189 |
|
✗ |
const graph::GraphPtr_t& StateHistogram::constraintGraph() const { |
190 |
|
✗ |
return graph_; |
191 |
|
|
} |
192 |
|
|
|
193 |
|
✗ |
HistogramPtr_t StateHistogram::clone() const { |
194 |
|
✗ |
return HistogramPtr_t(new StateHistogram(constraintGraph())); |
195 |
|
|
} |
196 |
|
|
|
197 |
|
✗ |
unsigned int LeafBin::numberOfObsOutOfConnectedComponent( |
198 |
|
|
const core::ConnectedComponentPtr_t& cc) const { |
199 |
|
✗ |
unsigned int count = 0; |
200 |
|
✗ |
for (RoadmapNodes_t::const_iterator it = nodes_.begin(); it != nodes_.end(); |
201 |
|
✗ |
++it) |
202 |
|
✗ |
if ((*it)->connectedComponent() != cc) count++; |
203 |
|
✗ |
return count; |
204 |
|
|
} |
205 |
|
|
|
206 |
|
|
statistics::DiscreteDistribution<RoadmapNodePtr_t> |
207 |
|
✗ |
LeafHistogram::getDistribOutOfConnectedComponent( |
208 |
|
|
const core::ConnectedComponentPtr_t& cc) const { |
209 |
|
✗ |
statistics::DiscreteDistribution<RoadmapNodePtr_t> distrib; |
210 |
|
✗ |
for (const_iterator bin = begin(); bin != end(); ++bin) { |
211 |
|
✗ |
unsigned int w = bin->numberOfObsOutOfConnectedComponent(cc); |
212 |
|
✗ |
if (w == 0) continue; |
213 |
|
✗ |
distrib.insert(bin->nodes().front(), w); |
214 |
|
|
} |
215 |
|
✗ |
return distrib; |
216 |
|
|
} |
217 |
|
|
|
218 |
|
✗ |
statistics::DiscreteDistribution<RoadmapNodePtr_t> LeafHistogram::getDistrib() |
219 |
|
|
const { |
220 |
|
✗ |
statistics::DiscreteDistribution<RoadmapNodePtr_t> distrib; |
221 |
|
✗ |
for (const_iterator bin = begin(); bin != end(); ++bin) { |
222 |
|
✗ |
std::size_t w = bin->freq(); |
223 |
|
✗ |
if (w == 0) continue; |
224 |
|
✗ |
distrib.insert(bin->nodes().front(), w); |
225 |
|
|
} |
226 |
|
✗ |
return distrib; |
227 |
|
|
} |
228 |
|
|
|
229 |
|
✗ |
const LeafBin::RoadmapNodes_t& LeafBin::nodes() const { return nodes_; } |
230 |
|
|
|
231 |
|
✗ |
bool Foliation::contains(ConfigurationIn_t q) const { |
232 |
|
✗ |
return condition_->isSatisfied(q); |
233 |
|
|
} |
234 |
|
|
|
235 |
|
✗ |
vector_t Foliation::parameter(ConfigurationIn_t q) const { |
236 |
|
✗ |
if (!condition_->isSatisfied(q)) { |
237 |
|
|
hppDout(error, "Configuration not in the foliation"); |
238 |
|
|
} |
239 |
|
✗ |
return parametrizer_->configProjector()->rightHandSideFromConfig(q); |
240 |
|
|
} |
241 |
|
|
|
242 |
|
✗ |
ConstraintSetPtr_t Foliation::condition() const { return condition_; } |
243 |
|
|
|
244 |
|
✗ |
void Foliation::condition(const ConstraintSetPtr_t c) { condition_ = c; } |
245 |
|
|
|
246 |
|
✗ |
ConstraintSetPtr_t Foliation::parametrizer() const { return parametrizer_; } |
247 |
|
|
|
248 |
|
✗ |
void Foliation::parametrizer(const ConstraintSetPtr_t p) { parametrizer_ = p; } |
249 |
|
|
} // namespace graph |
250 |
|
|
} // namespace manipulation |
251 |
|
|
} // namespace hpp |
252 |
|
|
|