PageRenderTime 60ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/tpie/deadcode/point.h

https://github.com/thomasmoelhave/tpie
C Header | 456 lines | 328 code | 69 blank | 59 comment | 80 complexity | cee44b3289406220da769663389a4850 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0
  1. // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-file-style: "stroustrup"; -*-
  2. // vi:set ts=4 sts=4 sw=4 noet :
  3. // Copyright 2008, The TPIE development team
  4. //
  5. // This file is part of TPIE.
  6. //
  7. // TPIE is free software: you can redistribute it and/or modify it under
  8. // the terms of the GNU Lesser General Public License as published by the
  9. // Free Software Foundation, either version 3 of the License, or (at your
  10. // option) any later version.
  11. //
  12. // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
  13. // WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  15. // License for more details.
  16. //
  17. // You should have received a copy of the GNU Lesser General Public License
  18. // along with TPIE. If not, see <http://www.gnu.org/licenses/>
  19. // The point and record classes.
  20. #ifndef TPIE_AMI_POINT_H_
  21. #define TPIE_AMI_POINT_H_
  22. // For ostream.
  23. #include <iostream>
  24. namespace tpie {
  25. namespace ami {
  26. // This is a hack. It works for integer types only.
  27. template<class coord_t>
  28. class infinity_t {
  29. static coord_t minf;// = (1 << (8*sizeof(coord_t) - 1));
  30. static coord_t pinf;// = ~minf;
  31. public:
  32. int operator+() const { return pinf; }
  33. int operator-() const { return minf; }
  34. };
  35. template<class coord_t>
  36. coord_t infinity_t<coord_t>::minf = (1 << (8*sizeof(coord_t) - 1));
  37. template<class coord_t>
  38. coord_t infinity_t<coord_t>::pinf = ~(1 << (8*sizeof(coord_t) - 1));
  39. //int infinity_t<int>::minf = (1 << (8*sizeof(int) - 1));
  40. //int infinity_t<int>::pinf = ~(1 << (8*sizeof(int) - 1));
  41. // The base class for point.
  42. template<class coord_t, size_t dim>
  43. class point_base {
  44. protected:
  45. coord_t coords_[dim];
  46. public:
  47. static infinity_t<coord_t> Inf;
  48. // The default constructor.
  49. point_base() {}
  50. // The array operators for accessing/setting the coordinates.
  51. coord_t& operator[](size_t i) { return coords_[i]; }
  52. const coord_t& operator[](size_t i) const { return coords_[i]; }
  53. // Operator < for window queries. It's actually more like <=.
  54. bool operator<(const point_base<coord_t, dim>& p) const {
  55. size_t i;
  56. for (i = 0; i < dim; i++)
  57. if (p[i] < coords_[i])
  58. break;
  59. return (i == dim);
  60. }
  61. void set_min(const point_base<coord_t, dim>& p) {
  62. for (size_t j = 0; j < dim; j++)
  63. coords_[j] = min(coords_[j], p[j]);
  64. }
  65. void set_max(const point_base<coord_t, dim>& p) {
  66. for (size_t j = 0; j < dim; j++)
  67. coords_[j] = max(coords_[j], p[j]);
  68. }
  69. // Scalar product.
  70. coord_t operator*(const point_base<coord_t,dim>& p) const {
  71. coord_t ans = coords_[0]*p[0];
  72. for (size_t i = 1; i < dim; i++)
  73. ans += coords_[i]*p[i];
  74. return ans;
  75. }
  76. };
  77. template<class coord_t, size_t dim>
  78. infinity_t<coord_t> point_base<coord_t, dim>::Inf = infinity_t<coord_t>();
  79. // The point class.
  80. template <class coord_t, size_t dim>
  81. class point: public point_base<coord_t, dim> {
  82. protected:
  83. using point_base<coord_t, dim>::coords_;
  84. public:
  85. bool operator==(const point<coord_t, dim>& p) const {
  86. size_t i = 0;
  87. while (i < dim) {
  88. if (coords_[i] != p[i])
  89. break;
  90. i++;
  91. }
  92. return (i == dim);
  93. }
  94. // The comparison class. For sorting on each of the dim dimensions.
  95. class cmp {
  96. // The dimension on which to compare. It should be less than dim.
  97. size_t d_;
  98. public:
  99. cmp(size_t d = 0): d_(d) {}
  100. inline int compare(const point<coord_t,dim>& p1,
  101. const point<coord_t,dim>& p2) const {
  102. // Lexicographic order starting with dimension d_.
  103. if (p1[d_] < p2[d_])
  104. return -1;
  105. else if (p1[d_] > p2[d_])
  106. return 1;
  107. else
  108. return _compare(p1, p2);
  109. }
  110. // This operator is used by STL sort().
  111. bool operator()(const point<coord_t, dim>& p1,
  112. const point<coord_t, dim>& p2) const {
  113. return (compare(p1, p2) == -1);
  114. }
  115. private:
  116. int _compare(const point<coord_t,dim>& p1,
  117. const point<coord_t,dim>& p2) const {
  118. size_t j = 0;
  119. // Cycle once through all dimensions, starting with d_.
  120. while (j < dim && p1[(j+d_)%dim] == p2[(j+d_)%dim])
  121. j++;
  122. if (j == dim)
  123. return 0;
  124. else
  125. return (p1[(j+d_)%dim] < p2[(j+d_)%dim]) ? -1: 1;
  126. }
  127. };
  128. };
  129. template<class coord_t, size_t dim>
  130. std::ostream& operator<<(std::ostream& s, const point<coord_t, dim>& p) {
  131. for (size_t i = 0; i < dim-1; i++)
  132. s << p[i] << " ";
  133. return s << p[dim-1];
  134. }
  135. #ifdef _WIN32
  136. #else
  137. // Partial specialization of point for 2 dimensions.
  138. template <class coord_t>
  139. class point<coord_t, 2>: public point_base<coord_t, 2> {
  140. protected:
  141. using point_base<coord_t, 2>::coords_;
  142. public:
  143. point() {}
  144. point(coord_t _x, coord_t _y) { coords_[0] = _x; coords_[1] = _y; }
  145. coord_t x() const { return coords_[0]; }
  146. coord_t& x() { return coords_[0]; }
  147. coord_t y() const { return coords_[1]; }
  148. coord_t& y() { return coords_[1]; }
  149. bool operator==(const point<coord_t, 2>& p) const {
  150. return (coords_[0] == p.coords_[0]) &&
  151. (coords_[1] == p.coords_[1]);
  152. }
  153. bool operator!=(const point<coord_t, 2>& p) const {
  154. return (coords_[0] != p.coords_[0]) ||
  155. (coords_[1] != p.coords_[1]);
  156. }
  157. bool less_x(const point<coord_t, 2>& b) const {
  158. return (coords_[0] < b.coords_[0]) ||
  159. ((coords_[0] == b.coords_[0]) && (coords_[1] < b.coords_[1]));
  160. }
  161. bool less_y(const point<coord_t, 2>& b) const {
  162. return (coords_[1] < b.coords_[1]) ||
  163. ((coords_[1] == b.coords_[1]) && (coords_[0] < b.coords_[0]));
  164. }
  165. struct less_X {
  166. bool operator()(const point<coord_t, 2>& a,
  167. const point<coord_t, 2>& b) const
  168. { return (a[0] < b[0]) || ((a[0] == b[0]) && (a[1] < b[1])); }
  169. };
  170. struct less_Y {
  171. bool operator()(const point<coord_t, 2>& a,
  172. const point<coord_t, 2>& b) const
  173. { return (a[1] < b[1]) || ((a[1] == b[1]) && (a[0] < b[0])); }
  174. };
  175. // The comparison class. For sorting on each of the dim dimensions.
  176. class cmp {
  177. // The dimension on which to compare. It should be less than 2.
  178. size_t d_;
  179. public:
  180. cmp(size_t d = 0): d_(d) {}
  181. inline int compare(const point<coord_t, 2>& p1,
  182. const point<coord_t, 2>& p2) const {
  183. // Lexicographic order starting with dimension d_.
  184. if (p1[d_] < p2[d_])
  185. return -1;
  186. else if (p1[d_] > p2[d_])
  187. return 1;
  188. else if (p1[(d_+1)%2] < p2[(d_+1)%2])
  189. return -1;
  190. else if (p2[(d_+1)%2] < p1[(d_+1)%2])
  191. return 1;
  192. else
  193. return 0;
  194. }
  195. // This operator is used by STL sort().
  196. bool operator()(const point<coord_t, 2>& p1,
  197. const point<coord_t, 2>& p2) const {
  198. return (compare(p1, p2) == -1);
  199. }
  200. };
  201. };
  202. template<class coord_t>
  203. std::ostream& operator<<(std::ostream& s, const point<coord_t, 2>& p) {
  204. return s << p[0] << " " << p[1];
  205. }
  206. #endif // !_WIN32
  207. template<class coord_t, class data_t, size_t dim>
  208. class record_base {
  209. public:
  210. typedef point<coord_t, dim> point_t;
  211. point_t key;
  212. data_t data;
  213. // record() {}
  214. record_base(const point_t& p, data_t _data = data_t(0)):
  215. key(p), data(_data) {}
  216. record_base(data_t _data = data_t(0)): data(_data) {}
  217. data_t& id() { return data; }
  218. const data_t& id() const { return data; }
  219. bool operator==(const record_base<coord_t, data_t, dim>& r) const
  220. { return key == r.key; }
  221. // The array operators for accessing/setting the coordinates.
  222. coord_t& operator[](size_t i) { return key[i]; }
  223. const coord_t& operator[](size_t i) const { return key[i]; }
  224. // Operator < for window queries. It's actually more like <=.
  225. bool operator<(const record_base<coord_t, data_t, dim>& p) const {
  226. size_t i;
  227. for (i = 0; i < dim; i++)
  228. if (p[i] < key[i])
  229. break;
  230. return (i == dim);
  231. }
  232. void set_min(const record_base<coord_t, data_t, dim>& p) {
  233. for (size_t j = 0; j < dim; j++)
  234. key[j] = min(key[j], p[j]);
  235. }
  236. void set_max(const record_base<coord_t, data_t, dim>& p) {
  237. for (size_t j = 0; j < dim; j++)
  238. key[j] = max(key[j], p[j]);
  239. }
  240. // Scalar product.
  241. coord_t operator*(const record_base<coord_t, data_t, dim>& p) const {
  242. coord_t ans = key[0] * p[0];
  243. for (size_t i = 1; i < dim; i++)
  244. ans += key[i] * p[i];
  245. return ans;
  246. }
  247. };
  248. template<class coord_t, class data_t, size_t dim>
  249. class record: public record_base<coord_t, data_t, dim> {
  250. public:
  251. record(const typename record_base<coord_t, data_t, dim>::point_t& p, data_t b = data_t(0)):
  252. record_base<coord_t, data_t, dim>(p, b) {}
  253. record(data_t b = data_t(0)): record_base<coord_t, data_t, dim>(b) {}
  254. // The comparison class. For sorting on each of the dim dimensions.
  255. class cmp {
  256. // The dimension on which to compare. It should be less than dim.
  257. size_t d_;
  258. public:
  259. cmp(size_t d = 0): d_(d) {}
  260. inline int compare(const record<coord_t, data_t, dim>& p1,
  261. const record<coord_t, data_t, dim>& p2) const {
  262. // Lexicographic order starting with dimension d_.
  263. if (p1[d_] < p2[d_])
  264. return -1;
  265. else if (p2[d_] < p1[d_])
  266. return 1;
  267. else
  268. return _compare(p1, p2);
  269. }
  270. // This operator is used by STL sort().
  271. bool operator()(const record<coord_t, data_t, dim>& p1,
  272. const record<coord_t, data_t, dim>& p2) const {
  273. return (compare(p1, p2) == -1);
  274. }
  275. private:
  276. int _compare(const record<coord_t, data_t, dim>& p1,
  277. const record<coord_t, data_t, dim>& p2) const {
  278. size_t j = 0;
  279. // Cycle once through all dimensions, starting with d_.
  280. // TODO: change equality expression to an expression containing only <.
  281. while (j < dim && p1[(j+d_)%dim] == p2[(j+d_)%dim])
  282. j++;
  283. if (j == dim)
  284. return 0;
  285. else
  286. return (p1[(j+d_)%dim] < p2[(j+d_)%dim]) ? -1: 1;
  287. }
  288. };
  289. };
  290. #ifdef _WIN32
  291. #else
  292. // A record consists of a key (two-dimensional point) and a data
  293. // item. Used by the EPStree.
  294. template<class coord_t, class data_t>
  295. class record<coord_t, data_t, 2>: public record_base<coord_t, data_t, 2> {
  296. public:
  297. record(const typename record_base<coord_t, data_t, 2>::point_t& p, data_t b = data_t(0)):
  298. record_base<coord_t, data_t, 2>(p, b) {}
  299. record(const coord_t& x, const coord_t& y, const data_t& b):
  300. record_base<coord_t, data_t, 2>(point_t(x, y), b) {}
  301. record(data_t b = data_t(0)): record_base<coord_t, data_t, 2>(b) {}
  302. struct less_X_point {
  303. bool operator()(const record<coord_t, data_t, 2>& r,
  304. const typename record_base<coord_t, data_t, 2>::point_t& p) const {
  305. // return point_t::less_X()(r.key, p);
  306. return r.key.less_x(p);
  307. }
  308. };
  309. struct less_X {
  310. bool operator()(const record<coord_t, data_t, 2>& r1,
  311. const record<coord_t, data_t, 2>& r2) const {
  312. // return point_t::less_X()(r1.key, r2.key);
  313. return r1.key.less_x(r2.key);
  314. }
  315. int compare(const record<coord_t, data_t, 2>& r1,
  316. const record<coord_t, data_t, 2>& r2) const {
  317. if (r1.key.less_x(r2.key))
  318. return -1;
  319. else if (r2.key.less_x(r1.key))
  320. return 1;
  321. else
  322. return 0;
  323. }
  324. };
  325. struct less_Y {
  326. bool operator()(const record<coord_t, data_t, 2>& r1,
  327. const record<coord_t, data_t, 2>& r2) const {
  328. // return point_t::less_Y()(r1.key, r2.key);
  329. return r1.key.less_y(r2.key);
  330. }
  331. int compare(const record<coord_t, data_t, 2>& r1,
  332. const record<coord_t, data_t, 2>& r2) const {
  333. if (r1.key.less_y(r2.key))
  334. return -1;
  335. else if (r2.key.less_y(r1.key))
  336. return 1;
  337. else
  338. return 0;
  339. }
  340. };
  341. // The comparison class. For sorting on each of the dim dimensions.
  342. class cmp {
  343. // The dimension on which to compare. It should be less than 2.
  344. size_t d_;
  345. public:
  346. cmp(size_t d = 0): d_(d) {}
  347. inline int compare(const record<coord_t, data_t, 2>& p1,
  348. const record<coord_t, data_t, 2>& p2) const {
  349. // Lexicographic order starting with dimension d_.
  350. if (p1[d_] < p2[d_])
  351. return -1;
  352. else if (p2[d_] < p1[d_])
  353. return 1;
  354. else if (p1[(d_+1)%2] < p2[(d_+1)%2])
  355. return -1;
  356. else if (p2[(d_+1)%2] < p1[(d_+1)%2])
  357. return 1;
  358. else
  359. return 0;
  360. }
  361. // This operator is used by STL sort().
  362. bool operator()(const record<coord_t, data_t, 2>& p1,
  363. const record<coord_t, data_t, 2>& p2) const {
  364. return (compare(p1, p2) == -1);
  365. }
  366. };
  367. };
  368. #endif // !_WIN32
  369. template<class coord_t, class data_t, size_t dim>
  370. std::ostream& operator<<(std::ostream& s, const record<coord_t, data_t, dim>& p) {
  371. for (size_t i=0; i < dim; ++i) s << p[i] << " ";
  372. return s << p.id();
  373. }
  374. template<class coord_t, class data_t, size_t dim>
  375. std::istream & operator>>(std::istream& s, record<coord_t, data_t, dim>& p) {
  376. for (size_t i=0; i < dim; ++i) s >> p[i];
  377. return s >> p.id();
  378. }
  379. // Function object to extract the key from a record.
  380. template<class coord_t, class data_t, size_t dim>
  381. class record_key {
  382. public:
  383. point<coord_t, dim> operator()(const record<coord_t, data_t, dim>& r) const
  384. { return r.key; }
  385. };
  386. } } //end namespace tpie::ami
  387. #endif // TPIE_AMI_POINT_H_