simple_discr.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "simple_discr.h"
  2. // change the tuple; return bool: "success"
  3. int step_tuple(int *tuple, int dim, int max)
  4. {
  5. int i=0;
  6. while ((i<dim) && (tuple[i] == max-1)) {
  7. tuple[i++]=0;
  8. }
  9. if (i<dim) {
  10. tuple[i]++;
  11. return 1;
  12. }
  13. else {
  14. return 0;
  15. }
  16. }
  17. // pos1 is coord-wise <= pos2
  18. int point_in_box(double *pos1, double *pos2, int dim)
  19. {
  20. int i;
  21. for (i=0; i<dim; i++)
  22. if (pos1[i] > pos2[i])
  23. return 0;
  24. return 1;
  25. }
  26. // assuming point in box, is point also on edge?
  27. int point_on_edge(double *pos1, double *pos2, int dim)
  28. {
  29. int i;
  30. for (i=0; i<dim; i++)
  31. if (fabs(pos1[i]-pos2[i])<1e-10)
  32. return 1;
  33. return 0;
  34. }
  35. double box_discr(double **pointset, int npoints, int dim,
  36. double *point)
  37. {
  38. double discr=1.0, discr2;
  39. int i, inbox=0, onedge=0;
  40. for (i=0; i<dim; i++)
  41. discr *= point[i];
  42. for (i=0; i<npoints; i++)
  43. if (point_in_box(pointset[i], point, dim)) {
  44. inbox++;
  45. if (point_on_edge(pointset[i], point, dim))
  46. onedge++;
  47. }
  48. // fprintf(stderr, "Points %d+%d vol %lg", inbox, onedge, discr);
  49. discr -= (double)inbox/npoints;
  50. discr2 = discr + (double)onedge/npoints;
  51. discr = fabs(discr);
  52. discr2 = fabs(discr2);
  53. // fprintf(stderr, " values %lg,%lg\n", discr, discr2);
  54. return (discr > discr2) ? discr : discr2;
  55. }
  56. double exact_discr(double **pointset, int npoints, int dim)
  57. {
  58. double *point, **coords, maxdiscr=0.0, discr;
  59. int i,j, *tuple;
  60. point = malloc(dim*sizeof(double));
  61. tuple = malloc(dim*sizeof(int));
  62. coords = malloc(dim*sizeof(double *));
  63. for (i=0; i<dim; i++) {
  64. tuple[i]=0;
  65. coords[i] = malloc((npoints+1)*sizeof(double));
  66. for (j=0; j<npoints; j++)
  67. coords[i][j] = pointset[j][i];
  68. coords[i][npoints]=1.0;
  69. }
  70. tuple[0]=-1;
  71. while (step_tuple(tuple, dim, npoints+1)) {
  72. for (i=0; i<dim; i++)
  73. point[i] = coords[i][tuple[i]];
  74. discr = box_discr(pointset, npoints, dim, point);
  75. if (discr > maxdiscr) {
  76. fprintf(stderr, "Point (%g", point[0]);
  77. for (i=1; i<dim; i++)
  78. fprintf(stderr, ", %g", point[i]);
  79. fprintf(stderr, ") discr %g\n", discr);
  80. maxdiscr = discr;
  81. }
  82. }
  83. return maxdiscr;
  84. }
  85. double rnd_coord_discr(double **pointset, int npoints, int dim, int trials)
  86. {
  87. double *point, **coords, maxdiscr=0.0, discr;
  88. int i,j;
  89. point = malloc(dim*sizeof(double));
  90. coords = malloc(dim*sizeof(double *));
  91. for (i=0; i<dim; i++) {
  92. coords[i] = malloc((npoints+1)*sizeof(double));
  93. for (j=0; j<npoints; j++)
  94. coords[i][j] = pointset[j][i];
  95. coords[i][npoints]=1.0;
  96. }
  97. for (i=0; i<trials; i++) {
  98. for (j=0; j<dim; j++)
  99. point[j] = coords[j][random()%(npoints+1)];
  100. discr = box_discr(pointset, npoints, dim, point);
  101. if (discr > maxdiscr) {
  102. fprintf(stderr, "%d/%d: discr %g\n", i, trials, discr);
  103. maxdiscr = discr;
  104. }
  105. }
  106. return maxdiscr;
  107. }