|
| 1 | +#pragma once |
| 2 | +/** |
| 3 | + * Compute kernel between feature vector and support vector. |
| 4 | + * Kernel type: linear |
| 5 | + */ |
| 6 | +double compute_kernel(double x[4], ...) { |
| 7 | + va_list w; |
| 8 | + double kernel = 0.0; |
| 9 | + va_start(w, 4); |
| 10 | + for (uint16_t i = 0; i < 4; i++) |
| 11 | + kernel += x[i] * va_arg(w, double); |
| 12 | + return kernel; |
| 13 | +} |
| 14 | +/** |
| 15 | + * Predict class for features vector |
| 16 | + */ |
| 17 | +int predict(double *x) { |
| 18 | + double kernels[15] = { 0 }; |
| 19 | + double decisions[6] = { 0 }; |
| 20 | + int votes[3] = { 0 }; |
| 21 | + kernels[0] = compute_kernel(x, 6.9 , 3.1 , 4.9 , 1.5 ); |
| 22 | + kernels[1] = compute_kernel(x, 5.7 , 2.8 , 4.5 , 1.3 ); |
| 23 | + kernels[2] = compute_kernel(x, 6.3 , 3.3 , 4.7 , 1.6 ); |
| 24 | + kernels[3] = compute_kernel(x, 4.9 , 2.4 , 3.3 , 1.0 ); |
| 25 | + kernels[4] = compute_kernel(x, 6.1 , 2.9 , 4.7 , 1.4 ); |
| 26 | + kernels[5] = compute_kernel(x, 5.6 , 3.0 , 4.5 , 1.5 ); |
| 27 | + kernels[6] = compute_kernel(x, 6.2 , 2.2 , 4.5 , 1.5 ); |
| 28 | + kernels[7] = compute_kernel(x, 4.9 , 2.5 , 4.5 , 1.7 ); |
| 29 | + kernels[8] = compute_kernel(x, 6.5 , 3.2 , 5.1 , 2.0 ); |
| 30 | + kernels[9] = compute_kernel(x, 6.4 , 2.7 , 5.3 , 1.9 ); |
| 31 | + kernels[10] = compute_kernel(x, 6.5 , 3.0 , 5.5 , 1.8 ); |
| 32 | + kernels[11] = compute_kernel(x, 6.0 , 2.2 , 5.0 , 1.5 ); |
| 33 | + kernels[12] = compute_kernel(x, 4.6 , 3.1 , 1.5 , 0.2 ); |
| 34 | + kernels[13] = compute_kernel(x, 5.4 , 3.9 , 1.7 , 0.4 ); |
| 35 | + kernels[14] = compute_kernel(x, 5.7 , 3.8 , 1.7 , 0.3 ); |
| 36 | + decisions[0] = 5.649189842276587 |
| 37 | + + kernels[0] * 0.8695514658046984 |
| 38 | + + kernels[1] * 0.06616679955553174 |
| 39 | + + kernels[2] * 0.8527543868372957 |
| 40 | + + kernels[4] |
| 41 | + + kernels[5] |
| 42 | + + kernels[6] |
| 43 | + - kernels[7] |
| 44 | + - kernels[8] |
| 45 | + + kernels[9] * -0.7884726521975259 |
| 46 | + - kernels[10] |
| 47 | + - kernels[11] |
| 48 | + ; |
| 49 | + decisions[1] = -1.3924837643789074 |
| 50 | + + kernels[3] * 0.45296487164978 |
| 51 | + + kernels[12] * -0.38073987478736276 |
| 52 | + + kernels[14] * -0.07222499686241728 |
| 53 | + ; |
| 54 | + decisions[2] = -1.2054358490148886 |
| 55 | + + kernels[7] * 0.1757465517828809 |
| 56 | + + kernels[12] * -0.09054230566349034 |
| 57 | + + kernels[13] * -0.08520424611939055 |
| 58 | + ; |
| 59 | + votes[decisions[0] > 0 ? 0 : 1] += 1; |
| 60 | + votes[decisions[1] > 0 ? 0 : 2] += 1; |
| 61 | + votes[decisions[2] > 0 ? 1 : 2] += 1; |
| 62 | + int classVal = -1; |
| 63 | + int classIdx = -1; |
| 64 | + for (int i = 0; i < 3; i++) { |
| 65 | + if (votes[i] > classVal) { |
| 66 | + classVal = votes[i]; |
| 67 | + classIdx = i; |
| 68 | + } |
| 69 | + } |
| 70 | + return classIdx; |
| 71 | +} |
| 72 | +/** |
| 73 | + * Convert class idx to readable name |
| 74 | + */ |
| 75 | +const char* classIdxToName(uint8_t classIdx) { |
| 76 | + switch (classIdx) { |
| 77 | + case 0: |
| 78 | + return "versicolor"; |
| 79 | + case 1: |
| 80 | + return "virginica"; |
| 81 | + case 2: |
| 82 | + return "setosa"; |
| 83 | + default: |
| 84 | + return "UNKNOWN"; |
| 85 | + } |
| 86 | +} |
0 commit comments