svm.c.t 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "svm.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #define New(t, n) (t *)malloc((n) * sizeof(t))
  6. #define Size @{size}
  7. #define Bias @{bias}
  8. #define Gama @{gama}
  9. #define Feat @{feat}
  10. static uint8_t okay = 0;
  11. // fill first number of each sv here
  12. static float Scales[Size] = {
  13. @{scales}
  14. };
  15. // fill element count of each sv here
  16. static uint32_t Elements[Size] = {
  17. @{elements}
  18. };
  19. // fill the flattened sv weights here
  20. static float Weights[] = {
  21. @{weights}
  22. };
  23. static Node *Vector[Size];
  24. void svm_init() {
  25. int i, j, idx = 0;
  26. for (i = 0; i < Size; ++i) {
  27. Vector[i] = New(Node, Elements[i] + 1);
  28. for (j = 0; j < Elements[i]; ++j, ++idx) {
  29. Vector[i][j].idx = j + 1;
  30. Vector[i][j].val = Weights[idx];
  31. }
  32. Vector[i][j].idx = 0;
  33. }
  34. okay = 1;
  35. }
  36. Node *input() {
  37. Node *x = New(Node, Feat + 1);
  38. int i;
  39. for (i = 0; i < Feat; ++i) {
  40. x[i].idx = i + 1;
  41. scanf("%f", &x[i].val); // NOLINT
  42. }
  43. x[Feat].idx = 0;
  44. return x;
  45. }
  46. float rbf_kernel(const Node *x, const Node *y) {
  47. float sum = 0;
  48. while (x->idx != 0 && y->idx != 0) {
  49. if (x->idx == y->idx) {
  50. float d = x->val - y->val;
  51. sum += d * d;
  52. ++x, ++y;
  53. } else {
  54. if (x->idx > y->idx) {
  55. sum += y->val * y->val;
  56. ++y;
  57. } else {
  58. sum += x->val * x->val;
  59. ++x;
  60. }
  61. }
  62. }
  63. while (x->idx != 0) {
  64. sum += x->val * x->val;
  65. ++x;
  66. }
  67. while (y->idx != -0) {
  68. sum += y->val * y->val;
  69. ++y;
  70. }
  71. return expf(-Gama * sum);
  72. }
  73. int8_t svm_predict(const Node *x) {
  74. if (okay == 0) {
  75. printf("you should call `svm_init();` first.");
  76. return 0;
  77. }
  78. float sum = -Bias;
  79. uint32_t i;
  80. for (i = 0; i < Size; ++i) sum += Scales[i] * rbf_kernel(x, Vector[i]);
  81. return sum > 0 ? 1 : -1;
  82. }