28 if (i1 == i2)
return false;
29 const base_node &pt1((i1 ==
size_type(-1)) ? *c : (*vbn)[i1]);
30 const base_node &pt2((i2 ==
size_type(-1)) ? *c : (*vbn)[i2]);
31 unsigned d = pt1.size();
32 base_small_vector::const_iterator it = v.begin();
33 base_node::const_iterator it1 = pt1.begin(), it2 = pt2.begin();
35 for (
size_type i = 0; i < d; ++i) a += (*it++) * (*it1++ - *it2++);
36 if (a != scalar_type(0))
return a < 0;
41 node_tab::component_comp::component_comp
42 (
const dal::dynamic_tas<base_node> &vbn_,
const base_node &c_,
unsigned dim)
43 : vbn(&vbn_), c(&c_), v(dim) {
45 gmm::scale(v, scalar_type(1) / gmm::vect_norm2(v) );
48 void node_tab::add_sorter(
void)
const {
49 if (sorters.size() > 1)
50 GMM_WARNING3(
"Multiple sort needed for node tab : " << sorters.size()+1);
51 sorters.push_back(sorter(component_comp(*
this, c, dim_)));
52 for (dal::bv_visitor i(index()); !i.finished(); ++i)
57 const scalar_type radius)
const {
58 if (card() == 0)
return size_type(-1);
60 scalar_type eps_radius = std::max(eps, radius);
61 for (size_type is = 0; is < 5; ++is) {
62 if (is >= sorters.size()) add_sorter();
64 c = pt - eps_radius * sorters[is].key_comp().v;
66 sorter::const_iterator it = sorters[is].lower_bound(size_type(-1));
68 = gmm::vect_sp(pt, sorters[is].key_comp().v) + 2*eps_radius;
71 for (; it != sorters[is].end() && count < 20; ++it, ++count) {
79 if (gmm::vect_dist2(pt, pt2) < eps_radius)
return *it;
80 if (gmm::vect_sp(pt2, sorters[is].key_comp().v) > up_bound)
83 if (it == sorters[is].
end())
return size_type(-1);
85 GMM_ASSERT1(
false,
"Problem in node structure !!");
89 dal::dynamic_tas<base_node>::clear();
90 sorters = std::vector<sorter>();
91 max_radius = scalar_type(1e-60);
92 eps = max_radius * prec_factor;
96 const scalar_type radius,
97 bool remove_duplicated_nodes) {
98 scalar_type npt = gmm::vect_norm2(pt);
99 max_radius = std::max(max_radius, npt);
100 eps = max_radius * prec_factor;
103 if (this->card() == 0) {
105 id = dal::dynamic_tas<base_node>::add(pt);
106 for (size_type i = 0; i < sorters.size(); ++i) sorters[i].insert(
id);
109 GMM_ASSERT1(dim_ == pt.size(),
"Nodes should have the same dimension");
110 id = remove_duplicated_nodes ?
search_node(pt, radius) : size_type(-1);
111 if (
id == size_type(-1)) {
112 id = dal::dynamic_tas<base_node>::add(pt);
113 for (size_type i = 0; i < sorters.size(); ++i) {
114 sorters[i].insert(
id);
115 GMM_ASSERT3(sorters[i].
size() == card(),
"internal error");
122 void node_tab::swap_points(size_type i, size_type j) {
124 bool existi = index().is_in(i), existj = index().is_in(j);
125 for (size_type is = 0; is < sorters.size(); ++is) {
126 if (existi) sorters[is].erase(i);
127 if (existj) sorters[is].erase(j);
129 dal::dynamic_tas<base_node>::swap(i, j);
130 for (size_type is = 0; is < sorters.size(); ++is) {
131 if (existi) sorters[is].insert(j);
132 if (existj) sorters[is].insert(i);
133 GMM_ASSERT3(sorters[is].
size() == card(),
"internal error");
138 void node_tab::sup_node(size_type i) {
139 if (index().is_in(i)) {
140 for (size_type is = 0; is < sorters.size(); ++is) {
141 sorters[is].erase(i);
142 GMM_ASSERT3(sorters[is].
size()+1 == card(),
"Internal error");
145 dal::dynamic_tas<base_node>::sup(i);
151 for (dal::bv_visitor i(index()); !i.finished(); ++i) (*
this)[i] += V;
155 void node_tab::transformation(
const base_matrix &M) {
157 GMM_ASSERT1(gmm::mat_nrows(M) != 0 && gmm::mat_ncols(M) == dim(),
158 "invalid dimensions for the transformation matrix");
159 dim_ = unsigned(gmm::mat_nrows(M));
160 for (dal::bv_visitor i(index()); !i.finished(); ++i) {
162 gmm::resize((*
this)[i], dim_);
163 gmm::mult(M,w,(*
this)[i]);
168 node_tab::node_tab(scalar_type prec_loose) {
169 max_radius = scalar_type(1e-60);
171 prec_factor = gmm::default_tol(scalar_type()) * prec_loose;
172 eps = max_radius * prec_factor;
175 node_tab::node_tab(
const node_tab &t)
176 : dal::dynamic_tas<base_node>(t), sorters(), eps(t.eps),
177 prec_factor(t.prec_factor), max_radius(t.max_radius), dim_(t.dim_) {}
180 dal::dynamic_tas<base_node>::operator =(t);
181 sorters = std::vector<sorter>();
182 eps = t.eps; prec_factor = t.prec_factor;
183 max_radius = t.max_radius; dim_ = t.dim_;
void clear(void)
reset the array, remove all points
void fill_random(L &l, double cfill)
*/
Structure which dynamically collects points identifying points that are nearer than a certain very sm...
size_t size_type
used as the common size type in the library
size_type search_node(const base_node &pt, const scalar_type radius=0) const
Search a node in the array.
size_type size(void) const
Number of allocated elements.
Store a set of points, identifying points that are nearer than a certain very small distance...
iterator end(void)
Iterator on the last + 1 element.
size_type add_node(const base_node &pt, const scalar_type radius=0, bool remove_duplicated_nodes=true)
Add a point to the array or identify it with a very close existing point.