123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- #include "svm.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #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;
- }
|