OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ExtensionFunctions.hpp
Go to the documentation of this file.
1 #include "../Shared/funcannotations.h"
2 #ifndef __CUDACC__
3 #include <cstdint>
4 
5 #ifdef _MSC_VER
6 #include <corecrt_math_defines.h>
7 #endif
8 
9 #endif
10 
11 #include <cmath>
12 #include <cstdlib>
13 
14 #include "heavydbTypes.h"
15 
16 /* Example extension functions:
17  *
18  * EXTENSION_NOINLINE
19  * int32_t diff(const int32_t x, const int32_t y) {
20  * return x - y;
21  *
22  * Arrays map to a pair of pointer and element count. The pointer type must be
23  * consistent with the element type of the array column. Only array of numbers
24  * are supported for the moment. For example, an ARRAY_AT function which works
25  * for arrays of INTEGER and SMALLINT can be implemented as follows:
26  *
27  * EXTENSION_NOINLINE
28  * int64_t array_at(const int32_t* arr, const size_t elem_count, const size_t idx) {
29  * return idx < elem_count ? arr[idx] : -1;
30  * }
31  *
32  * EXTENSION_NOINLINE
33  * int64_t array_at__(const int16_t* arr, const size_t elem_count, const size_t idx) {
34  * return idx < elem_count ? arr[idx] : -1;
35  * }
36  *
37  * Note that the return type cannot be specialized and must be the same across
38  * all specializations. We can remove this constraint in the future if necessary.
39  */
40 
42 double Acos(const double x) {
43  return acos(x);
44 }
45 
47 double Asin(const double x) {
48  return asin(x);
49 }
50 
52 double Atan(const double x) {
53  return atan(x);
54 }
55 
57 double Atanh(const double x) {
58  return atanh(x);
59 }
60 
62 double Atan2(const double y, const double x) {
63  return atan2(y, x);
64 }
65 
67 double Ceil(double x) {
68  return ceil(x);
69 }
70 
72 float Ceil__(float x) {
73  return ceil(x);
74 }
75 
77 int16_t Ceil__1(int16_t x) {
78  return x;
79 }
80 
82 int32_t Ceil__2(int32_t x) {
83  return x;
84 }
85 
87 int64_t Ceil__3(int64_t x) {
88  return x;
89 }
90 
92 double Cos(const double x) {
93  return cos(x);
94 }
95 
97 double Cosh(const double x) {
98  return cosh(x);
99 }
100 
102 double Cot(const double x) {
103  return 1 / tan(x);
104 }
105 
107 double degrees(double x) {
108  return x * (180.0 / M_PI);
109 }
110 
112 double Exp(double x) {
113  return exp(x);
114 }
115 
117 double Floor(double x) {
118  return floor(x);
119 }
120 
122 float Floor__(float x) {
123  return floor(x);
124 }
125 
127 int16_t Floor__1(int16_t x) {
128  return x;
129 }
130 
132 int32_t Floor__2(int32_t x) {
133  return x;
134 }
135 
137 int64_t Floor__3(int64_t x) {
138  return x;
139 }
140 
142 double ln(const double x) {
143  return log(x);
144 }
145 
147 double ln__(const float x) {
148  return logf(x);
149 }
150 
152 double Log(const double x) {
153  return log(x);
154 }
155 
157 double Log__(const float x) {
158  return logf(x);
159 }
160 
162 double Log10(const double x) {
163  return log10(x);
164 }
165 
167 double Log10__(const float x) {
168  return log10f(x);
169 }
170 
172 double pi() {
173  return M_PI;
174 }
175 
177 double power(const double x, const double y) {
178  return pow(x, y);
179 }
180 
182 double radians(const double x) {
183  return x * (M_PI / 180.0);
184 }
185 
187 double Round(const double x, const int32_t y) {
188  if (y == 0) {
189  return round(x) + 0.0;
190  }
191 
192  double exp = pow(10, y);
193 #if defined(__powerpc__) && !defined(__CUDACC__)
194  int32_t yy = y - 1;
195  exp = 10 * powf((float)10L, yy);
196 #endif
197  return (round(x * exp) / exp) + 0.0;
198 }
199 
201 float Round__(const float x, const int32_t y) {
202  if (y == 0) {
203  return roundf(x) + 0.0f;
204  }
205 
206  float exp = powf((float)10L, y);
207 #if defined(__powerpc__) && !defined(__CUDACC__)
208  int32_t yy = y - 1;
209  exp = 10 * powf((float)10L, yy);
210 #endif
211  return roundf(x * exp) / exp + 0.0f;
212 }
213 
215 int16_t Round__1(const int16_t x, const int32_t y) {
216  if (y >= 0) {
217  return x;
218  }
219 
220  int32_t p = pow((float)10L, std::abs(y));
221  int32_t p_half = p >> 1;
222 
223  int64_t temp = x;
224 #if defined(__powerpc__) && !defined(__CUDACC__)
225  int16_t xx = x;
226  xx += 1;
227  temp = xx;
228  temp -= 1;
229 #endif
230  temp = temp >= 0 ? temp + p_half : temp - p_half;
231  temp = temp / p;
232  return temp * p;
233 }
234 
236 int32_t Round__2(const int32_t x, const int32_t y) {
237  if (y >= 0) {
238  return x;
239  }
240 
241  int32_t p = pow((float)10L, std::abs(y));
242  int32_t p_half = p >> 1;
243 
244  int64_t temp = x;
245 #if defined(__powerpc__) && !defined(__CUDACC__)
246  int32_t xx = x;
247  xx += 1;
248  temp = xx;
249  temp -= 1;
250 #endif
251  temp = temp >= 0 ? temp + p_half : temp - p_half;
252  temp = temp / p;
253  return temp * p;
254 }
255 
257 int64_t Round__3(const int64_t x, const int32_t y) {
258  if (y >= 0) {
259  return x;
260  }
261 
262  int64_t p = pow((double)10L, std::abs(y));
263  int64_t p_half = p >> 1;
264 
265  int64_t temp = x;
266  temp = temp >= 0 ? temp + p_half : temp - p_half;
267  temp = temp / p;
268  return temp * p;
269 }
270 
272 int64_t Round__4(const int64_t x, const int32_t y0, const int32_t scale) {
273  int32_t y = y0 - scale;
274 
275  if (y >= 0) {
276  return x;
277  }
278 
279  int64_t p = pow((double)10L, std::abs(y));
280  int64_t p_half = p >> 1;
281 
282  int64_t temp = x;
283  temp = temp >= 0 ? temp + p_half : temp - p_half;
284  temp = temp / p;
285  return temp * p;
286 }
287 
289 double Round2_to_digit(const double x, const int32_t y) {
290  double exp = pow(10, y);
291  return round(x * exp) / exp;
292 }
293 
295 double round_to_digit(const double x, const int32_t y) {
296  double exp = pow(10, y);
297  return round(x * exp) / exp;
298 }
299 
301 double Sin(const double x) {
302  return sin(x);
303 }
304 
306 double Sinh(const double x) {
307  return sinh(x);
308 }
309 
311 double Sqrt(const double x) {
312  return sqrt(x);
313 }
314 
316 double Tan(const double x) {
317  return tan(x);
318 }
319 
321 double Tanh(const double x) {
322  return tanh(x);
323 }
324 
326 double Tan__(const float x) {
327  return tanf(x);
328 }
329 
331 double Truncate(const double x, const int32_t y) {
332  double p = pow((double)10L, y);
333  int64_t temp = x * p;
334  return temp / p;
335 }
336 
338 float Truncate__(const float x, const int32_t y) {
339  float p = powf((float)10L, y);
340  int64_t temp = x * p;
341  return temp / p;
342 }
343 
345 int16_t Truncate__1(const int16_t x, const int32_t y) {
346  if (y >= 0) {
347  return x;
348  }
349  int32_t p = pow((float)10L, std::abs(y));
350  int64_t temp = x / p;
351 #if defined(__powerpc__) && !defined(__CUDACC__)
352  int16_t xx = x;
353  xx += 1;
354  temp = xx;
355  temp -= 1;
356  temp /= p;
357 #endif
358  return temp * p;
359 }
360 
362 int32_t Truncate__2(const int32_t x, const int32_t y) {
363  if (y >= 0) {
364  return x;
365  }
366  int32_t p = pow((float)10L, std::abs(y));
367  int64_t temp = x / p;
368  return temp * p;
369 }
370 
372 int64_t Truncate__3(const int64_t x, const int32_t y) {
373  if (y >= 0) {
374  return x;
375  }
376  int64_t p = pow((double)10L, std::abs(y));
377  int64_t temp = x / p;
378  return temp * p;
379 }
380 
382 bool is_nan(const double x) {
383  return std::isnan(x);
384 }
385 
387 bool is_nan__(const float x) {
388  return std::isnan(x);
389 }
390 
392 bool is_inf(const double x) {
393  return std::isinf(x);
394 }
395 
397 bool is_inf__(const float x) {
398  return std::isinf(x);
399 }
400 
402 double conv_4326_900913_x(const double x) {
403  return x * 111319.490778;
404 }
405 
407 double conv_4326_900913_y(const double y) {
408  return 6378136.99911 * log(tan(.00872664626 * y + .785398163397));
409 }
410 
433 double distance_in_meters(const double fromlon,
434  const double fromlat,
435  const double tolon,
436  const double tolat) {
437  double latitudeArc = (fromlat - tolat) * 0.017453292519943295769236907684886;
438  double longitudeArc = (fromlon - tolon) * 0.017453292519943295769236907684886;
439  double latitudeH = sin(latitudeArc * 0.5);
440  latitudeH *= latitudeH;
441  double lontitudeH = sin(longitudeArc * 0.5);
442  lontitudeH *= lontitudeH;
443  double tmp = cos(fromlat * 0.017453292519943295769236907684886) *
444  cos(tolat * 0.017453292519943295769236907684886);
445  return 6372797.560856 * (2.0 * asin(sqrt(latitudeH + tmp * lontitudeH)));
446 }
447 
449 double distance_in_meters__(const float fromlon,
450  const float fromlat,
451  const float tolon,
452  const float tolat) {
453  float latitudeArc = (fromlat - tolat) * 0.017453292519943295769236907684886;
454  float longitudeArc = (fromlon - tolon) * 0.017453292519943295769236907684886;
455  float latitudeH = sinf(latitudeArc * 0.5);
456  latitudeH *= latitudeH;
457  float lontitudeH = sinf(longitudeArc * 0.5);
458  lontitudeH *= lontitudeH;
459  float tmp = cosf(fromlat * 0.017453292519943295769236907684886) *
460  cosf(tolat * 0.017453292519943295769236907684886);
461  return 6372797.560856 * (2.0 * asinf(sqrtf(latitudeH + tmp * lontitudeH)));
462 }
463 
465 double approx_distance_in_meters(const float fromlon,
466  const float fromlat,
467  const float tolon,
468  const float tolat) {
469 #ifdef __CUDACC__
470  float latitudeArc = (fromlat - tolat) * 0.017453292519943295769236907684886;
471  float longitudeArc = (fromlon - tolon) * 0.017453292519943295769236907684886;
472  float latitudeH = __sinf(latitudeArc * 0.5);
473  latitudeH *= latitudeH;
474  float lontitudeH = __sinf(longitudeArc * 0.5);
475  lontitudeH *= lontitudeH;
476  float tmp = __cosf(fromlat * 0.017453292519943295769236907684886) *
477  __cosf(tolat * 0.017453292519943295769236907684886);
478  return 6372797.560856 * (2.0 * asinf(__fsqrt_rd(latitudeH + tmp * lontitudeH)));
479 #else
480  return distance_in_meters__(fromlon, fromlat, tolon, tolat);
481 #endif
482 }
483 
485 float rect_pixel_bin(const double val,
486  const double min,
487  const double max,
488  const int32_t numbins,
489  const int32_t dimensionsize) {
491  float numbinsf = float(numbins);
492  return float(int32_t(float((val - min) / (max - min)) * numbinsf)) *
493  float(dimensionsize) / numbinsf;
494 }
495 
497 float rect_pixel_bin_x(const double valx,
498  const double minx,
499  const double maxx,
500  const double rectwidth,
501  const double offsetx,
502  const int32_t imgwidth) {
503  const float imgwidthf = float(imgwidth);
504  const float rectwidthf = float(rectwidth);
505  double min = minx;
506  float offset = offsetx;
507  if (offset != 0) {
508  offset = fmodf(offset, rectwidthf);
509  if (offset > 0) {
510  offset -= rectwidthf;
511  }
512  min += offset * (maxx - minx) / imgwidthf;
513  }
514  return float(int32_t(float((valx - min) / (maxx - min)) * (imgwidthf - offset) /
515  rectwidthf)) *
516  rectwidthf +
517  offset + rectwidthf / 2.0f;
518 }
519 
521 float rect_pixel_bin_y(const double valy,
522  const double miny,
523  const double maxy,
524  const double rectheight,
525  const double offsety,
526  const int32_t imgheight) {
527  const float imgheightf = float(imgheight);
528  const float rectheightf = rectheight;
529  double min = miny;
530  float offset = offsety;
531  if (offset != 0) {
532  offset = fmodf(offset, rectheightf);
533  if (offset > 0) {
534  offset -= rectheightf;
535  }
536  min += offset * (maxy - miny) / imgheightf;
537  }
538  return float(int32_t(float((valy - min) / (maxy - min)) * (imgheightf - offset) /
539  rectheightf)) *
540  rectheightf +
541  offset + rectheightf / 2.0f;
542 }
543 
545 int32_t rect_pixel_bin_packed(const double valx,
546  const double minx,
547  const double maxx,
548  const double valy,
549  const double miny,
550  const double maxy,
551  const double rectwidth,
552  const double rectheight,
553  const double offsetx,
554  const double offsety,
555  const int32_t imgwidth,
556  const int32_t imgheight) {
557  const float imgwidthf = float(imgwidth);
558  const float rectwidthf = float(rectwidth);
559  double min = minx;
560  float offset = offsetx;
561  if (offset != 0) {
562  offset = fmodf(offset, rectwidthf);
563  if (offset > 0) {
564  offset -= rectwidthf;
565  }
566  min += offset * (maxx - minx) / imgwidthf;
567  }
568  float rx = float(int32_t(float((valx - min) / (maxx - min)) * (imgwidthf - offset) /
569  rectwidthf)) *
570  rectwidthf +
571  offset + rectwidthf / 2.0f;
572 
573  const float imgheightf = float(imgheight);
574  const float rectheightf = rectheight;
575  min = miny;
576  offset = offsety;
577  if (offset != 0) {
578  offset = fmodf(offset, rectheightf);
579  if (offset > 0) {
580  offset -= rectheightf;
581  }
582  min += offset * (maxy - miny) / imgheightf;
583  }
584  float ry = float(int32_t(float((valy - min) / (maxy - min)) * (imgheightf - offset) /
585  rectheightf)) *
586  rectheightf +
587  offset + rectheightf / 2.0f;
588 
589  // and pack as two 14.2 fixed-point values into 32bits
590  int32_t ux = static_cast<int32_t>(rx * 4.0f);
591  int32_t uy = static_cast<int32_t>(ry * 4.0f);
592  return (ux & 0x7FFF) | ((uy & 0x7FFF) << 16);
593 }
594 
596 float reg_hex_horiz_pixel_bin_x(const double valx,
597  const double minx,
598  const double maxx,
599  const double valy,
600  const double miny,
601  const double maxy,
602  const double hexwidth,
603  const double hexheight,
604  const double offsetx,
605  const double offsety,
606  const int32_t imgwidth,
607  const int32_t imgheight) {
608  const float sqrt3 = 1.7320508075688772;
609  const float imgwidthf = float(imgwidth);
610  const float imgheightf = float(imgheight);
611  const float hexwidthf = float(hexwidth);
612  const float hexheightf = float(hexheight);
613 
614  // expand the bounds of the data according
615  // to the input offsets. This is done because
616  // we also expand the image size according to the
617  // offsets because this algorithm layers the hexagon
618  // bins starting at the bottom left corner
619  double xmin = minx;
620  float xoffset = offsetx;
621  if (xoffset != 0) {
622  xoffset = fmodf(xoffset, hexwidthf);
623  if (xoffset > 0) {
624  xoffset -= hexwidthf;
625  }
626  xmin += xoffset * (maxx - xmin) / imgwidthf;
627  }
628 
629  double ymin = miny;
630  float yoffset = offsety;
631  if (yoffset != 0) {
632  yoffset = fmodf(yoffset, 1.5f * hexheightf);
633  if (yoffset > 0) {
634  yoffset -= 1.5f * hexheightf;
635  }
636  ymin += yoffset * (maxy - ymin) / imgheightf;
637  }
638 
639  // get the pixel position of the point
640  // assumes a linear scale here
641  // Rounds to the nearest pixel.
642  const float pix_x =
643  roundf((imgwidthf - xoffset) * float((valx - xmin) / (maxx - xmin)));
644  const float pix_y =
645  roundf((imgheightf - yoffset) * float((valy - ymin) / (maxy - ymin)));
646 
647  // Now convert the pixel position into a
648  // cube-coordinate system representation
649  const float hexsize = hexheightf / 2.0f;
650  const float cube_x = ((pix_x / sqrt3) - (pix_y / 3.0f)) / hexsize;
651  const float cube_z = (pix_y * 2.0f / 3.0f) / hexsize;
652  const float cube_y = -cube_x - cube_z;
653 
654  // need to round the cube coordinates above
655  float rx = round(cube_x);
656  float ry = round(cube_y);
657  float rz = round(cube_z);
658  const float x_diff = fabs(rx - cube_x);
659  const float y_diff = fabs(ry - cube_y);
660  const float z_diff = fabs(rz - cube_z);
661  if (x_diff > y_diff && x_diff > z_diff) {
662  rx = -ry - rz;
663  } else if (y_diff > z_diff) {
664  ry = -rx - rz;
665  } else {
666  rz = -rx - ry;
667  }
668 
669  // now convert the cube/hex coord to a pixel location
670  return hexsize * sqrt3 * (rx + rz / 2.0f) + xoffset;
671 }
672 
674 float reg_hex_horiz_pixel_bin_y(const double valx,
675  const double minx,
676  const double maxx,
677  const double valy,
678  const double miny,
679  const double maxy,
680  const double hexwidth,
681  const double hexheight,
682  const double offsetx,
683  const double offsety,
684  const int32_t imgwidth,
685  const int32_t imgheight) {
686  const float sqrt3 = 1.7320508075688772;
687  const float imgwidthf = float(imgwidth);
688  const float imgheightf = float(imgheight);
689  const float hexwidthf = float(hexwidth);
690  const float hexheightf = float(hexheight);
691 
692  // expand the bounds of the data according
693  // to the input offsets. This is done because
694  // we also expand the image size according to the
695  // offsets because this algorithm layers the hexagon
696  // bins starting at the bottom left corner
697  double xmin = minx;
698  float xoffset = offsetx;
699  if (xoffset != 0) {
700  xoffset = fmodf(xoffset, hexwidthf);
701  if (xoffset > 0) {
702  xoffset -= hexwidthf;
703  }
704  xmin += xoffset * (maxx - xmin) / imgwidthf;
705  }
706 
707  double ymin = miny;
708  float yoffset = offsety;
709  if (yoffset != 0) {
710  yoffset = fmodf(yoffset, 1.5f * hexheightf);
711  if (yoffset > 0) {
712  yoffset -= 1.5f * hexheightf;
713  }
714  ymin += yoffset * (maxy - ymin) / imgheightf;
715  }
716 
717  // get the pixel position of the point
718  // assumes a linear scale here
719  // Rounds to the nearest pixel.
720  const float pix_x =
721  roundf((imgwidthf - xoffset) * float((valx - xmin) / (maxx - xmin)));
722  const float pix_y =
723  roundf((imgheightf - yoffset) * float((valy - ymin) / (maxy - ymin)));
724 
725  // Now convert the pixel position into a
726  // cube-coordinate system representation
727  const float hexsize = hexheightf / 2.0f;
728  const float cube_x = ((pix_x / sqrt3) - (pix_y / 3.0f)) / hexsize;
729  const float cube_z = (pix_y * 2.0f / 3.0f) / hexsize;
730  const float cube_y = -cube_x - cube_z;
731 
732  // need to round the cube coordinates above
733  float rx = round(cube_x);
734  float ry = round(cube_y);
735  float rz = round(cube_z);
736  const float x_diff = fabs(rx - cube_x);
737  const float y_diff = fabs(ry - cube_y);
738  const float z_diff = fabs(rz - cube_z);
739  if ((x_diff <= y_diff || x_diff <= z_diff) && y_diff <= z_diff) {
740  rz = -rx - ry;
741  }
742 
743  // now convert the cube/hex coord to a pixel location
744  return hexsize * 3.0f / 2.0f * rz + yoffset;
745 }
746 
748 int32_t reg_hex_horiz_pixel_bin_packed(const double valx,
749  const double minx,
750  const double maxx,
751  const double valy,
752  const double miny,
753  const double maxy,
754  const double hexwidth,
755  const double hexheight,
756  const double offsetx,
757  const double offsety,
758  const int32_t imgwidth,
759  const int32_t imgheight) {
760  const float sqrt3 = 1.7320508075688772;
761  const float imgwidthf = float(imgwidth);
762  const float imgheightf = float(imgheight);
763  const float hexwidthf = float(hexwidth);
764  const float hexheightf = float(hexheight);
765 
766  // expand the bounds of the data according
767  // to the input offsets. This is done because
768  // we also expand the image size according to the
769  // offsets because this algorithm layers the hexagon
770  // bins starting at the bottom left corner
771  double xmin = minx;
772  float xoffset = offsetx;
773  if (xoffset != 0) {
774  xoffset = fmodf(xoffset, hexwidthf);
775  if (xoffset > 0) {
776  xoffset -= hexwidthf;
777  }
778  xmin += xoffset * (maxx - xmin) / imgwidthf;
779  }
780 
781  double ymin = miny;
782  float yoffset = offsety;
783  if (yoffset != 0) {
784  yoffset = fmodf(yoffset, 1.5f * hexheightf);
785  if (yoffset > 0) {
786  yoffset -= 1.5f * hexheightf;
787  }
788  ymin += yoffset * (maxy - ymin) / imgheightf;
789  }
790 
791  // get the pixel position of the point
792  // assumes a linear scale here
793  // Rounds to the nearest pixel.
794  const float pix_x =
795  roundf((imgwidthf - xoffset) * float((valx - xmin) / (maxx - xmin)));
796  const float pix_y =
797  roundf((imgheightf - yoffset) * float((valy - ymin) / (maxy - ymin)));
798 
799  // Now convert the pixel position into a
800  // cube-coordinate system representation
801  const float hexsize = hexheightf / 2.0f;
802  const float cube_x = ((pix_x / sqrt3) - (pix_y / 3.0f)) / hexsize;
803  const float cube_z = (pix_y * 2.0f / 3.0f) / hexsize;
804  const float cube_y = -cube_x - cube_z;
805 
806  // need to round the cube coordinates above
807  float rx = round(cube_x);
808  float ry = round(cube_y);
809  float rz = round(cube_z);
810  const float x_diff = fabs(rx - cube_x);
811  const float y_diff = fabs(ry - cube_y);
812  const float z_diff = fabs(rz - cube_z);
813  if (x_diff > y_diff && x_diff > z_diff) {
814  rx = -ry - rz;
815  } else if (y_diff <= z_diff) {
816  rz = -rx - ry;
817  }
818 
819  // now convert the cube/hex coord to pixel locations
820  float hx = hexsize * sqrt3 * (rx + rz / 2.0f) + xoffset;
821  float hy = hexsize * 3.0f / 2.0f * rz + yoffset;
822 
823  // and pack as two 14.2 fixed-point values into 32bits
824  int32_t ux = static_cast<int32_t>(hx * 4.0f);
825  int32_t uy = static_cast<int32_t>(hy * 4.0f);
826  return (ux & 0x7FFF) | ((uy & 0x7FFF) << 16);
827 }
828 
830 float reg_hex_vert_pixel_bin_x(const double valx,
831  const double minx,
832  const double maxx,
833  const double valy,
834  const double miny,
835  const double maxy,
836  const double hexwidth,
837  const double hexheight,
838  const double offsetx,
839  const double offsety,
840  const int32_t imgwidth,
841  const int32_t imgheight) {
842  const float sqrt3 = 1.7320508075688772;
843  const float imgwidthf = float(imgwidth);
844  const float imgheightf = float(imgheight);
845  const float hexwidthf = float(hexwidth);
846  const float hexheightf = float(hexheight);
847 
848  // expand the bounds of the data according
849  // to the input offsets. This is done because
850  // we also expand the image size according to the
851  // offsets because this algorithm layers the hexagon
852  // bins starting at the bottom left corner
853  double xmin = minx;
854  float xoffset = offsetx;
855  if (xoffset != 0) {
856  xoffset = fmodf(xoffset, 1.5f * hexwidthf);
857  if (xoffset > 0) {
858  xoffset -= 1.5f * hexwidthf;
859  }
860  xmin += xoffset * (maxx - xmin) / imgwidthf;
861  }
862 
863  double ymin = miny;
864  float yoffset = offsety;
865  if (yoffset != 0) {
866  yoffset = fmodf(yoffset, hexheightf);
867  if (yoffset > 0) {
868  yoffset -= hexheightf;
869  }
870  ymin += yoffset * (maxy - ymin) / imgheightf;
871  }
872 
873  // get the pixel position of the point
874  // assumes a linear scale here
875  // Rounds to the nearest pixel.
876  const float pix_x =
877  roundf((imgwidthf - xoffset) * float((valx - xmin) / (maxx - xmin)));
878  const float pix_y =
879  roundf((imgheightf - yoffset) * float((valy - ymin) / (maxy - ymin)));
880 
881  // Now convert the pixel position into a
882  // cube-coordinate system representation
883  const float hexsize = hexwidthf / 2.0f;
884  const float cube_x = (pix_x * 2.0f / 3.0f) / hexsize;
885  const float cube_z = ((pix_y / sqrt3) - (pix_x / 3.0f)) / hexsize;
886  const float cube_y = -cube_x - cube_z;
887 
888  // need to round the cube coordinates above
889  float rx = round(cube_x);
890  float ry = round(cube_y);
891  float rz = round(cube_z);
892  const float x_diff = fabs(rx - cube_x);
893  const float y_diff = fabs(ry - cube_y);
894  const float z_diff = fabs(rz - cube_z);
895  if (x_diff > y_diff && x_diff > z_diff) {
896  rx = -ry - rz;
897  }
898 
899  // now convert the cube/hex coord to a pixel location
900  return hexsize * 3.0f / 2.0f * rx + xoffset;
901 }
902 
904 float reg_hex_vert_pixel_bin_y(const double valx,
905  const double minx,
906  const double maxx,
907  const double valy,
908  const double miny,
909  const double maxy,
910  const double hexwidth,
911  const double hexheight,
912  const double offsetx,
913  const double offsety,
914  const int32_t imgwidth,
915  const int32_t imgheight) {
916  const float sqrt3 = 1.7320508075688772;
917  const float imgwidthf = float(imgwidth);
918  const float imgheightf = float(imgheight);
919  const float hexwidthf = float(hexwidth);
920  const float hexheightf = float(hexheight);
921 
922  // expand the bounds of the data according
923  // to the input offsets. This is done because
924  // we also expand the image size according to the
925  // offsets because this algorithm layers the hexagon
926  // bins starting at the bottom left corner
927  float xmin = minx;
928  float xoffset = offsetx;
929  if (xoffset != 0) {
930  xoffset = fmodf(xoffset, 1.5f * hexwidthf);
931  if (xoffset > 0) {
932  xoffset -= 1.5f * hexwidthf;
933  }
934  xmin += xoffset * (maxx - xmin) / imgwidthf;
935  }
936 
937  float ymin = miny;
938  float yoffset = offsety;
939  if (yoffset != 0) {
940  yoffset = fmodf(yoffset, hexheightf);
941  if (yoffset > 0) {
942  yoffset -= hexheightf;
943  }
944  ymin += yoffset * (maxy - ymin) / imgheightf;
945  }
946 
947  // get the pixel position of the point
948  // assumes a linear scale here
949  // Rounds to the nearest pixel.
950  const float pix_x = roundf((imgwidthf - xoffset) * (valx - xmin) / (maxx - xmin));
951  const float pix_y = roundf((imgheightf - yoffset) * (valy - ymin) / (maxy - ymin));
952 
953  // Now convert the pixel position into a
954  // cube-coordinate system representation
955  const float hexsize = hexwidthf / 2.0f;
956  const float cube_x = (pix_x * 2.0f / 3.0f) / hexsize;
957  const float cube_z = ((pix_y / sqrt3) - (pix_x / 3.0f)) / hexsize;
958  const float cube_y = -cube_x - cube_z;
959 
960  // need to round the cube coordinates above
961  float rx = round(cube_x);
962  float ry = round(cube_y);
963  float rz = round(cube_z);
964  const float x_diff = fabs(rx - cube_x);
965  const float y_diff = fabs(ry - cube_y);
966  const float z_diff = fabs(rz - cube_z);
967  if (x_diff > y_diff && x_diff > z_diff) {
968  rx = -ry - rz;
969  } else if (y_diff > z_diff) {
970  ry = -rx - rz;
971  } else {
972  rz = -rx - ry;
973  }
974 
975  // now convert the cube/hex coord to a pixel location
976  return hexsize * sqrt3 * (rz + rx / 2.0f) + yoffset;
977 }
978 
980 int32_t reg_hex_vert_pixel_bin_packed(const double valx,
981  const double minx,
982  const double maxx,
983  const double valy,
984  const double miny,
985  const double maxy,
986  const double hexwidth,
987  const double hexheight,
988  const double offsetx,
989  const double offsety,
990  const int32_t imgwidth,
991  const int32_t imgheight) {
992  const float sqrt3 = 1.7320508075688772;
993  const float imgwidthf = float(imgwidth);
994  const float imgheightf = float(imgheight);
995  const float hexwidthf = float(hexwidth);
996  const float hexheightf = float(hexheight);
997 
998  // expand the bounds of the data according
999  // to the input offsets. This is done because
1000  // we also expand the image size according to the
1001  // offsets because this algorithm layers the hexagon
1002  // bins starting at the bottom left corner
1003  double xmin = minx;
1004  float xoffset = offsetx;
1005  if (xoffset != 0) {
1006  xoffset = fmodf(xoffset, 1.5f * hexwidthf);
1007  if (xoffset > 0) {
1008  xoffset -= 1.5f * hexwidthf;
1009  }
1010  xmin += xoffset * (maxx - xmin) / imgwidthf;
1011  }
1012 
1013  double ymin = miny;
1014  float yoffset = offsety;
1015  if (yoffset != 0) {
1016  yoffset = fmodf(yoffset, hexheightf);
1017  if (yoffset > 0) {
1018  yoffset -= hexheightf;
1019  }
1020  ymin += yoffset * (maxy - ymin) / imgheightf;
1021  }
1022 
1023  // get the pixel position of the point
1024  // assumes a linear scale here
1025  // Rounds to the nearest pixel.
1026  const float pix_x = roundf((imgwidthf - xoffset) * float(valx - xmin) / (maxx - xmin));
1027  const float pix_y = roundf((imgheightf - yoffset) * float(valy - ymin) / (maxy - ymin));
1028 
1029  // Now convert the pixel position into a
1030  // cube-coordinate system representation
1031  const float hexsize = hexwidthf / 2.0f;
1032  const float cube_x = (pix_x * 2.0f / 3.0f) / hexsize;
1033  const float cube_z = ((pix_y / sqrt3) - (pix_x / 3.0f)) / hexsize;
1034  const float cube_y = -cube_x - cube_z;
1035 
1036  // need to round the cube coordinates above
1037  float rx = round(cube_x);
1038  float ry = round(cube_y);
1039  float rz = round(cube_z);
1040  const float x_diff = fabs(rx - cube_x);
1041  const float y_diff = fabs(ry - cube_y);
1042  const float z_diff = fabs(rz - cube_z);
1043  if (x_diff > y_diff && x_diff > z_diff) {
1044  rx = -ry - rz;
1045  } else if (y_diff <= z_diff) {
1046  rz = -rx - ry;
1047  }
1048 
1049  // now convert the cube/hex coord to a pixel location
1050  float hx = hexsize * 3.0f / 2.0f * rx + xoffset;
1051  float hy = hexsize * sqrt3 * (rz + rx / 2.0f) + yoffset;
1052 
1053  // and pack as two 14.2 fixed-point values into 32bits
1054  int32_t ux = static_cast<int32_t>(hx * 4.0f);
1055  int32_t uy = static_cast<int32_t>(hy * 4.0f);
1056  return (ux & 0x7FFF) | ((uy & 0x7FFF) << 16);
1057 }
1058 
1060 double convert_meters_to_merc_pixel_width(const double meters,
1061  const double lon,
1062  const double lat,
1063  const double min_lon,
1064  const double max_lon,
1065  const int32_t img_width,
1066  const double min_width) {
1067  const double const1 = 0.017453292519943295769236907684886;
1068  const double const2 = 6372797.560856;
1069  double t1 = sinf(meters / (2.0 * const2));
1070  double t2 = cosf(const1 * lat);
1071  const double newlon = lon - (2.0 * asinf(t1 / t2)) / const1;
1072  t1 = conv_4326_900913_x(lon);
1073  t2 = conv_4326_900913_x(newlon);
1074  const double min_merc_x = conv_4326_900913_x(min_lon);
1075  const double max_merc_x = conv_4326_900913_x(max_lon);
1076  const double merc_diff = max_merc_x - min_merc_x;
1077  t1 = ((t1 - min_merc_x) / merc_diff) * static_cast<double>(img_width);
1078  t2 = ((t2 - min_merc_x) / merc_diff) * static_cast<double>(img_width);
1079 
1080  // TODO(croot): need to account for edge cases, such as getting close to the poles.
1081  const double sz = fabs(t1 - t2);
1082  return (sz < min_width ? min_width : sz);
1083 }
1084 
1086 double convert_meters_to_merc_pixel_height(const double meters,
1087  const double lon,
1088  const double lat,
1089  const double min_lat,
1090  const double max_lat,
1091  const int32_t img_height,
1092  const double min_height) {
1093  const double const1 = 0.017453292519943295769236907684886;
1094  const double const2 = 6372797.560856;
1095  const double latdiff = meters / (const1 * const2);
1096  const double newlat =
1097  (lat < 0) ? lat + latdiff : lat - latdiff; // assumes a lat range of [-90, 90]
1098  double t1 = conv_4326_900913_y(lat);
1099  double t2 = conv_4326_900913_y(newlat);
1100  const double min_merc_y = conv_4326_900913_y(min_lat);
1101  const double max_merc_y = conv_4326_900913_y(max_lat);
1102  const double merc_diff = max_merc_y - min_merc_y;
1103  t1 = ((t1 - min_merc_y) / merc_diff) * static_cast<double>(img_height);
1104  t2 = ((t2 - min_merc_y) / merc_diff) * static_cast<double>(img_height);
1105 
1106  // TODO(croot): need to account for edge cases, such as getting close to the poles.
1107  const double sz = fabs(t1 - t2);
1108  return (sz < min_height ? min_height : sz);
1109 }
1110 
1112  const double lat,
1113  const double min_lon,
1114  const double max_lon,
1115  const double min_lat,
1116  const double max_lat) {
1117  return !(lon < min_lon || lon > max_lon || lat < min_lat || lat > max_lat);
1118 }
1119 
1121  const double lat,
1122  const double meters,
1123  const double min_lon,
1124  const double max_lon,
1125  const double min_lat,
1126  const double max_lat) {
1127  const double const1 = 0.017453292519943295769236907684886;
1128  const double const2 = 6372797.560856;
1129  const double latdiff = meters / (const1 * const2);
1130  const double t1 = sinf(meters / (2.0 * const2));
1131  const double t2 = cosf(const1 * lat);
1132  const double londiff = (2.0 * asinf(t1 / t2)) / const1;
1133  return !(lon + londiff < min_lon || lon - londiff > max_lon ||
1134  lat + latdiff < min_lat || lat - latdiff > max_lat);
1135 }
1136 
1137 #include "ExtensionFunctionsArray.hpp"
1139 #include "ExtensionFunctionsGeo.hpp"
1141 #include "ExtensionFunctionsText.hpp"
EXTENSION_NOINLINE double Atanh(const double x)
EXTENSION_NOINLINE double ln(const double x)
EXTENSION_NOINLINE int32_t reg_hex_horiz_pixel_bin_packed(const double valx, const double minx, const double maxx, const double valy, const double miny, const double maxy, const double hexwidth, const double hexheight, const double offsetx, const double offsety, const int32_t imgwidth, const int32_t imgheight)
EXTENSION_NOINLINE float reg_hex_horiz_pixel_bin_x(const double valx, const double minx, const double maxx, const double valy, const double miny, const double maxy, const double hexwidth, const double hexheight, const double offsetx, const double offsety, const int32_t imgwidth, const int32_t imgheight)
EXTENSION_NOINLINE double Tan__(const float x)
EXTENSION_INLINE bool is_point_in_merc_view(const double lon, const double lat, const double min_lon, const double max_lon, const double min_lat, const double max_lat)
#define EXTENSION_NOINLINE
Definition: heavydbTypes.h:58
EXTENSION_NOINLINE bool is_nan__(const float x)
EXTENSION_NOINLINE double Sin(const double x)
H3Index functions.
EXTENSION_NOINLINE int32_t Truncate__2(const int32_t x, const int32_t y)
EXTENSION_NOINLINE double power(const double x, const double y)
EXTENSION_NOINLINE double Cot(const double x)
EXTENSION_NOINLINE int32_t rect_pixel_bin_packed(const double valx, const double minx, const double maxx, const double valy, const double miny, const double maxy, const double rectwidth, const double rectheight, const double offsetx, const double offsety, const int32_t imgwidth, const int32_t imgheight)
EXTENSION_NOINLINE int64_t Round__3(const int64_t x, const int32_t y)
EXTENSION_NOINLINE double distance_in_meters__(const float fromlon, const float fromlat, const float tolon, const float tolat)
EXTENSION_NOINLINE bool is_nan(const double x)
EXTENSION_NOINLINE int16_t Round__1(const int16_t x, const int32_t y)
EXTENSION_NOINLINE double Asin(const double x)
EXTENSION_NOINLINE double Log10(const double x)
EXTENSION_NOINLINE double convert_meters_to_merc_pixel_width(const double meters, const double lon, const double lat, const double min_lon, const double max_lon, const int32_t img_width, const double min_width)
EXTENSION_NOINLINE float Floor__(float x)
EXTENSION_NOINLINE int64_t Floor__3(int64_t x)
#define M_PI
Definition: constants.h:25
EXTENSION_NOINLINE double Ceil(double x)
EXTENSION_NOINLINE double Sqrt(const double x)
EXTENSION_NOINLINE int16_t Ceil__1(int16_t x)
EXTENSION_NOINLINE int64_t Truncate__3(const int64_t x, const int32_t y)
EXTENSION_NOINLINE int16_t Floor__1(int16_t x)
EXTENSION_NOINLINE double Exp(double x)
#define EXTENSION_INLINE
Definition: heavydbTypes.h:57
EXTENSION_NOINLINE double radians(const double x)
EXTENSION_NOINLINE double Cos(const double x)
EXTENSION_NOINLINE int64_t Round__4(const int64_t x, const int32_t y0, const int32_t scale)
EXTENSION_NOINLINE int32_t Ceil__2(int32_t x)
EXTENSION_NOINLINE float rect_pixel_bin_y(const double valy, const double miny, const double maxy, const double rectheight, const double offsety, const int32_t imgheight)
EXTENSION_NOINLINE int32_t Round__2(const int32_t x, const int32_t y)
EXTENSION_NOINLINE double Cosh(const double x)
EXTENSION_NOINLINE double Floor(double x)
EXTENSION_NOINLINE double Round2_to_digit(const double x, const int32_t y)
EXTENSION_NOINLINE double degrees(double x)
EXTENSION_NOINLINE double round_to_digit(const double x, const int32_t y)
EXTENSION_NOINLINE double convert_meters_to_merc_pixel_height(const double meters, const double lon, const double lat, const double min_lat, const double max_lat, const int32_t img_height, const double min_height)
EXTENSION_NOINLINE double Log__(const float x)
EXTENSION_NOINLINE float reg_hex_horiz_pixel_bin_y(const double valx, const double minx, const double maxx, const double valy, const double miny, const double maxy, const double hexwidth, const double hexheight, const double offsetx, const double offsety, const int32_t imgwidth, const int32_t imgheight)
EXTENSION_NOINLINE double ln__(const float x)
EXTENSION_NOINLINE float rect_pixel_bin(const double val, const double min, const double max, const int32_t numbins, const int32_t dimensionsize)
EXTENSION_NOINLINE float reg_hex_vert_pixel_bin_x(const double valx, const double minx, const double maxx, const double valy, const double miny, const double maxy, const double hexwidth, const double hexheight, const double offsetx, const double offsety, const int32_t imgwidth, const int32_t imgheight)
EXTENSION_NOINLINE int64_t Ceil__3(int64_t x)
EXTENSION_NOINLINE bool is_inf__(const float x)
EXTENSION_NOINLINE float Round__(const float x, const int32_t y)
torch::Tensor f(torch::Tensor x, torch::Tensor W_target, torch::Tensor b_target)
EXTENSION_NOINLINE float Truncate__(const float x, const int32_t y)
EXTENSION_NOINLINE double distance_in_meters(const double fromlon, const double fromlat, const double tolon, const double tolat)
Computes the distance, in meters, between two WGS-84 positions.
EXTENSION_NOINLINE double Round(const double x, const int32_t y)
EXTENSION_NOINLINE float Ceil__(float x)
EXTENSION_NOINLINE float reg_hex_vert_pixel_bin_y(const double valx, const double minx, const double maxx, const double valy, const double miny, const double maxy, const double hexwidth, const double hexheight, const double offsetx, const double offsety, const int32_t imgwidth, const int32_t imgheight)
EXTENSION_NOINLINE int32_t Floor__2(int32_t x)
EXTENSION_NOINLINE bool is_inf(const double x)
EXTENSION_NOINLINE double Truncate(const double x, const int32_t y)
EXTENSION_NOINLINE double Log(const double x)
EXTENSION_NOINLINE double approx_distance_in_meters(const float fromlon, const float fromlat, const float tolon, const float tolat)
EXTENSION_NOINLINE double Sinh(const double x)
EXTENSION_NOINLINE double Tanh(const double x)
EXTENSION_NOINLINE float rect_pixel_bin_x(const double valx, const double minx, const double maxx, const double rectwidth, const double offsetx, const int32_t imgwidth)
EXTENSION_NOINLINE double pi()
EXTENSION_NOINLINE int32_t reg_hex_vert_pixel_bin_packed(const double valx, const double minx, const double maxx, const double valy, const double miny, const double maxy, const double hexwidth, const double hexheight, const double offsetx, const double offsety, const int32_t imgwidth, const int32_t imgheight)
EXTENSION_NOINLINE double Tan(const double x)
EXTENSION_NOINLINE double Atan2(const double y, const double x)
EXTENSION_NOINLINE double conv_4326_900913_y(const double y)
EXTENSION_NOINLINE double Atan(const double x)
EXTENSION_NOINLINE double conv_4326_900913_x(const double x)
EXTENSION_NOINLINE double Log10__(const float x)
EXTENSION_NOINLINE bool is_point_size_in_merc_view(const double lon, const double lat, const double meters, const double min_lon, const double max_lon, const double min_lat, const double max_lat)
EXTENSION_NOINLINE int16_t Truncate__1(const int16_t x, const int32_t y)
EXTENSION_NOINLINE double Acos(const double x)