function.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. #include <math.h>
  2. #include <grass/gis.h>
  3. #include <grass/vector.h>
  4. #include <grass/glocale.h>
  5. #include "global.h"
  6. static double (*kernelfn)(double term, double bandwidth, double x);
  7. /*********************** Gaussian ****************************/
  8. /* probability for gaussian distribution */
  9. double gaussian2dBySigma(double d, double sigma)
  10. {
  11. double res;
  12. res =
  13. 1. / (2. * M_PI * sigma * sigma) * exp(-d * d / (2. * sigma * sigma));
  14. return (res);
  15. }
  16. double gaussianFunction(double x, double sigma, double dimension)
  17. {
  18. return ((1. / (pow(2. * M_PI, dimension / 2.) * pow(sigma, dimension))) *
  19. exp(-0.5 * pow(x / sigma, 2.)));
  20. }
  21. /* probability for gaussian distribution */
  22. double gaussianKernel(double x, double termx)
  23. {
  24. return (termx * exp(-(x * x) / 2.));
  25. }
  26. /*
  27. term1 = 1./(2.*M_PI*sigma*sigma)
  28. term2 = 2.*sigma*sigma;
  29. */
  30. double gaussian2dByTerms(double d, double term1, double term2)
  31. {
  32. double res;
  33. res = term1 * exp(-d * d / term2);
  34. return (res);
  35. }
  36. double segno(double x)
  37. {
  38. double y;
  39. y = (x > 0 ? 1. : 0.) + (x < 0 ? -1. : 0.);
  40. return y;
  41. }
  42. double kernel1(double d, double rs, double lambda)
  43. {
  44. double res;
  45. double a = lambda - 1.;
  46. if (lambda == 1.) {
  47. res = 1. / (M_PI * (d * d + rs * rs));
  48. }
  49. else {
  50. res = segno(a) * (a / M_PI) * (pow(rs, 2. * a)) *
  51. (1 / pow(d * d + rs * rs, lambda));
  52. }
  53. /* res=1./(M_PI*(d*d+rs*rs)); */
  54. return (res);
  55. }
  56. double invGaussian2d(double sigma, double prob)
  57. {
  58. double d;
  59. d = sqrt(-2 * sigma * sigma * log(prob * M_PI * 2 * sigma * sigma));
  60. return (d);
  61. }
  62. /* euclidean distance between vectors x and y of length n */
  63. double euclidean_distance(double *x, double *y, int n)
  64. {
  65. int j;
  66. double out = 0.0;
  67. double tmp;
  68. for (j = 0; j < n; j++) {
  69. tmp = x[j] - y[j];
  70. out += tmp * tmp;
  71. }
  72. return sqrt(out);
  73. }
  74. /*****************kernel density functions******************************/
  75. double gaussianKernel4(double term, double bandwidth, double x)
  76. {
  77. /* term is set by setKernelFunction */
  78. /* bandwidth is here SD */
  79. /*
  80. double term =
  81. 1. / (pow(bandwidth, dimension) * pow((2. * M_PI), dimension / 2.));
  82. */
  83. x /= bandwidth;
  84. /* SD = radius (bandwidth) / 4 */
  85. return (term * exp((x * x) / -2.));
  86. }
  87. /* Note: these functions support currently only 1D and 2D, consider this for example
  88. * before using them for 3d grid */
  89. double uniformKernel(double term, double bandwidth, double x)
  90. {
  91. /* term is set by setKernelFunction */
  92. if (x > bandwidth)
  93. return 0;
  94. /*
  95. if (dimension == 2)
  96. term = 2. / (M_PI * pow(bandwidth, 2));
  97. else
  98. term = 1. / bandwidth;
  99. term *= (1. / 2);
  100. x /= bandwidth;
  101. */
  102. return term;
  103. }
  104. double triangularKernel(double term, double bandwidth, double x)
  105. {
  106. /* term is set by setKernelFunction */
  107. if (x > bandwidth)
  108. return 0;
  109. /*
  110. if (dimension == 2)
  111. term = 3. / (M_PI * pow(bandwidth, 2));
  112. else
  113. term = 1. / bandwidth;
  114. */
  115. x /= bandwidth;
  116. return term * (1 - x);
  117. }
  118. double epanechnikovKernel(double term, double bandwidth, double x)
  119. {
  120. /* term is set by setKernelFunction */
  121. if (x > bandwidth)
  122. return 0;
  123. /*
  124. if (dimension == 2)
  125. term = 8. / (M_PI * 3. * pow(bandwidth, 2));
  126. else
  127. term = 1. / bandwidth;
  128. term *= (3. / 4.);
  129. */
  130. x /= bandwidth;
  131. /* return term * (3. / 4. * (1 - x * x)); */
  132. return term * (1 - x * x);
  133. }
  134. double quarticKernel(double term, double bandwidth, double x)
  135. {
  136. /* term is set by setKernelFunction */
  137. if (x > bandwidth)
  138. return 0;
  139. /*
  140. if (dimension == 2)
  141. term = 16. / (M_PI * 5. * pow(bandwidth, 2));
  142. else
  143. term = 1. / bandwidth;
  144. term *= (15. / 16.);
  145. */
  146. x /= bandwidth;
  147. /* return term * (15. / 16. * pow(1 - x * x, 2)); */
  148. return term * pow(1 - x * x, 2);
  149. }
  150. double triweightKernel(double term, double bandwidth, double x)
  151. {
  152. /* term is set by setKernelFunction */
  153. if (x > bandwidth)
  154. return 0;
  155. /*
  156. if (dimension == 2)
  157. term = 128. / (M_PI * 35. * pow(bandwidth, 2));
  158. else
  159. term = 1. / bandwidth;
  160. term *= (35. / 32);
  161. */
  162. x /= bandwidth;
  163. /* return term * (35. / 32 * pow(1 - x * x, 3)); */
  164. return term * pow(1 - x * x, 3);
  165. }
  166. double cosineKernel(double term, double bandwidth, double x)
  167. {
  168. /* term is set by setKernelFunction */
  169. if (x > bandwidth)
  170. return 0;
  171. /*
  172. if (dimension == 2)
  173. term = 1. / (2 * (M_PI / 2 - 1) * pow(bandwidth, 2));
  174. else
  175. term = 1. / bandwidth;
  176. term *= (M_PI / 4.);
  177. */
  178. x /= bandwidth;
  179. /* return term * (M_PI / 4. * cos(M_PI / 2. * x)); */
  180. return term * cos(M_PI / 2. * x);
  181. }
  182. double kernelFunction(double term, double bandwidth, double x)
  183. {
  184. return kernelfn(term, bandwidth, x);
  185. }
  186. void setKernelFunction(int function, int dimension, double bandwidth, double *term)
  187. {
  188. switch (function) {
  189. case KERNEL_UNIFORM:
  190. kernelfn = uniformKernel;
  191. if (dimension == 2)
  192. *term = 2. / (M_PI * pow(bandwidth, 2));
  193. else
  194. *term = 1. / bandwidth;
  195. *term *= (1. / 2);
  196. break;
  197. case KERNEL_TRIANGULAR:
  198. kernelfn = triangularKernel;
  199. if (dimension == 2)
  200. *term = 3. / (M_PI * pow(bandwidth, 2));
  201. else
  202. *term = 1. / bandwidth;
  203. break;
  204. case KERNEL_EPANECHNIKOV:
  205. kernelfn = epanechnikovKernel;
  206. if (dimension == 2)
  207. *term = 8. / (M_PI * 3. * pow(bandwidth, 2));
  208. else
  209. *term = 1. / bandwidth;
  210. *term *= (3. / 4.);
  211. break;
  212. case KERNEL_QUARTIC:
  213. kernelfn = quarticKernel;
  214. if (dimension == 2)
  215. *term = 16. / (M_PI * 5. * pow(bandwidth, 2));
  216. else
  217. *term = 1. / bandwidth;
  218. *term *= (15. / 16.);
  219. break;
  220. case KERNEL_TRIWEIGHT:
  221. kernelfn = triweightKernel;
  222. if (dimension == 2)
  223. *term = 128. / (M_PI * 35. * pow(bandwidth, 2));
  224. else
  225. *term = 1. / bandwidth;
  226. *term *= (35. / 32);
  227. break;
  228. case KERNEL_GAUSSIAN:
  229. kernelfn = gaussianKernel4;
  230. *term =
  231. 1. / (pow(bandwidth, dimension) * pow((2. * M_PI), dimension / 2.));
  232. break;
  233. case KERNEL_COSINE:
  234. kernelfn = cosineKernel;
  235. if (dimension == 2)
  236. *term = 1. / (2 * (M_PI / 2 - 1) * pow(bandwidth, 2));
  237. else
  238. *term = 1. / bandwidth;
  239. *term *= (M_PI / 4.);
  240. break;
  241. default:
  242. G_fatal_error("Unknown kernel function");
  243. }
  244. }