svm.c 2.0 KB

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