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

/src/util/select.c

https://gitlab.com/libtrilateration/libtrilateration
C | 87 lines | 50 code | 11 blank | 26 comment | 9 complexity | 5b85d6c94d91f0388efae8d91c1134e1 MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * This file is part of libtrilateration.
  3. *
  4. *
  5. * Copyright 2014 by Marcel Kyas
  6. *
  7. * libtrilateration is free software: you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation, either version 3 of the
  10. * License, or (at your option) any later version.
  11. *
  12. * libtrilateration is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with libtrilateration. If not, see
  19. * <http://www.gnu.org/licenses/>.
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. # include "libtrilateration/config.h"
  23. #endif
  24. #include <assert.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <libtrilateration/util.h>
  28. /*!
  29. * Find the kth element in sorted order of an array.
  30. *
  31. * Adapted from Wirth, Niklaus. "Algorithms + data structures = programs",
  32. * Englewood Cliffs: Prentice-Hall, 1976.
  33. */
  34. double
  35. trilateration_fselect(double const *const values, const size_t N,
  36. const int k)
  37. {
  38. double a[N];
  39. memcpy(a, values, N * sizeof(double));
  40. int l = 0, m = (int) N - 1;
  41. while (l < m) {
  42. double x = a[k];
  43. int i = l;
  44. int j = m;
  45. do {
  46. while (a[i] < x) {
  47. i++;
  48. }
  49. while (x < a[j]) {
  50. j--;
  51. }
  52. if (i <= j) {
  53. assert(0 <= i && i < (int) N);
  54. assert(0 <= j && j < (int) N);
  55. double t = a[i];
  56. a[i] = a[j];
  57. a[j] = t;
  58. i++;
  59. j--;
  60. }
  61. }
  62. while (i <= j);
  63. if (j < k) {
  64. l = i;
  65. }
  66. if (k < i) {
  67. m = j;
  68. }
  69. }
  70. return a[k];
  71. }
  72. double trilateration_fmedian(double const *const values, const size_t N)
  73. {
  74. const int k = (N / 2) - ((N & 1) ? 0 : 1);
  75. return trilateration_fselect(values, N, k);
  76. }