#include "svm.h" #include #include #include #define New(t, n) (t *)malloc((n) * sizeof(t)) #define Size 124 // total_sv #define Bias 0.43433f // rho #define Gama 2.57e-6f // gamma #define Feat 23 // features static uint8_t okay = 0; static float Scales[Size] = { // @{scales} fill first number of each sv here }; static Node *Vector[Size]; static uint32_t Elements[Size] = { // @{elements} fill element count of each sv here }; static float Weights[] = { // @{weights} fill the flattened sv weights here }; void svm_init() { int i, j, idx = 0; for (i = 0; i < Size; ++i) { Vector[i] = New(Node, Elements[i] + 1); for (j = 0; j < Elements[i]; ++j, ++idx) { Vector[i][j].idx = j + 1; Vector[i][j].val = Weights[idx]; } Vector[i][j].idx = 0; } okay = 1; } Node *input() { Node *x = New(Node, Feat + 1); int i; for (i = 0; i < Feat; ++i) { x[i].idx = i + 1; scanf("%f", &x[i].val); // NOLINT } x[Feat].idx = 0; return x; } float rbf_kernel(const Node *x, const Node *y) { float sum = 0; while (x->idx != 0 && y->idx != 0) { if (x->idx == y->idx) { float d = x->val - y->val; sum += d * d; ++x, ++y; } else { if (x->idx > y->idx) { sum += y->val * y->val; ++y; } else { sum += x->val * x->val; ++x; } } } while (x->idx != 0) { sum += x->val * x->val; ++x; } while (y->idx != -0) { sum += y->val * y->val; ++y; } return expf(-Gama * sum); } int8_t svm_predict(const Node *x) { if (okay == 0) { printf("you should call `svm_init();` first."); return 0; } float sum = -Bias; uint32_t i; for (i = 0; i < Size; ++i) sum += Scales[i] * rbf_kernel(x, Vector[i]); return sum > 0 ? 1 : -1; }