Advertisement
Guest User

Untitled

a guest
Apr 25th, 2017
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.96 KB | None | 0 0
  1. VR_knn(Sint *kin, Sint *lin, Sint *pntr, Sint *pnte, Sint *p,
  2. double *train, Sint *class, double *test, Sint *res, double *pr,
  3. Sint *votes, Sint *nc, Sint *cv, Sint *use_all)
  4. {
  5. int i, index, j, k, k1, kinit = *kin, kn, l = *lin, mm, npat, ntie,
  6. ntr = *pntr, nte = *pnte, extras;
  7. int pos[MAX_TIES], nclass[MAX_TIES];
  8. int j1, j2, needed, t;
  9. double dist, tmp, nndist[MAX_TIES];
  10.  
  11. RANDIN;
  12. /*
  13. Use a 'fence' in the (k+1)st position to avoid special cases.
  14. Simple insertion sort will suffice since k will be small.
  15. */
  16.  
  17. for (npat = 0; npat < nte; npat++) {
  18. kn = kinit;
  19. for (k = 0; k < kn; k++)
  20. nndist[k] = 0.99 * DOUBLE_XMAX;
  21. for (j = 0; j < ntr; j++) {
  22. if ((*cv > 0) && (j == npat))
  23. continue;
  24. dist = 0.0;
  25. for (k = 0; k < *p; k++) {
  26. tmp = test[npat + k * nte] - train[j + k * ntr];
  27. dist += tmp * tmp;
  28. }
  29. /* Use 'fuzz' since distance computed could depend on order of coordinates */
  30. if (dist <= nndist[kinit - 1] * (1 + EPS))
  31. for (k = 0; k <= kn; k++)
  32. if (dist < nndist[k]) {
  33. for (k1 = kn; k1 > k; k1--) {
  34. nndist[k1] = nndist[k1 - 1];
  35. pos[k1] = pos[k1 - 1];
  36. }
  37. nndist[k] = dist;
  38. pos[k] = j;
  39. /* Keep an extra distance if the largest current one ties with current kth */
  40. if (nndist[kn] <= nndist[kinit - 1])
  41. if (++kn == MAX_TIES - 1)
  42. error("too many ties in knn");
  43. break;
  44. }
  45. nndist[kn] = 0.99 * DOUBLE_XMAX;
  46. }
  47.  
  48. for (j = 0; j <= *nc; j++)
  49. votes[j] = 0;
  50. if (*use_all) {
  51. for (j = 0; j < kinit; j++)
  52. votes[class[pos[j]]]++;
  53. extras = 0;
  54. for (j = kinit; j < kn; j++) {
  55. if (nndist[j] > nndist[kinit - 1] * (1 + EPS))
  56. break;
  57. extras++;
  58. votes[class[pos[j]]]++;
  59. }
  60. } else { /* break ties at random */
  61. extras = 0;
  62. for (j = 0; j < kinit; j++) {
  63. if (nndist[j] >= nndist[kinit - 1] * (1 - EPS))
  64. break;
  65. votes[class[pos[j]]]++;
  66. }
  67. j1 = j;
  68. if (j1 == kinit - 1) { /* no ties for largest */
  69. votes[class[pos[j1]]]++;
  70. } else {
  71. /* Use reservoir sampling to choose amongst the tied distances */
  72. j1 = j;
  73. needed = kinit - j1;
  74. for (j = 0; j < needed; j++)
  75. nclass[j] = class[pos[j1 + j]];
  76. t = needed;
  77. for (j = j1 + needed; j < kn; j++) {
  78. if (nndist[j] > nndist[kinit - 1] * (1 + EPS))
  79. break;
  80. if (++t * UNIF < needed) {
  81. j2 = j1 + (int) (UNIF * needed);
  82. nclass[j2] = class[pos[j]];
  83. }
  84. }
  85. for (j = 0; j < needed; j++)
  86. votes[nclass[j]]++;
  87. }
  88. }
  89.  
  90. /* Use reservoir sampling to choose amongst the tied votes */
  91. ntie = 1;
  92. if (l > 0)
  93. mm = l - 1 + extras;
  94. else
  95. mm = 0;
  96. index = 0;
  97. for (i = 1; i <= *nc; i++)
  98. if (votes[i] > mm) {
  99. ntie = 1;
  100. index = i;
  101. mm = votes[i];
  102. } else if (votes[i] == mm && votes[i] >= l) {
  103. if (++ntie * UNIF < 1.0)
  104. index = i;
  105. }
  106. res[npat] = index;
  107. pr[npat] = (double) mm / (kinit + extras);
  108. }
  109. RANDOUT;
  110. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement