├── Arduino_SVM ├── Arduino_SVM.pde └── sketch.properties ├── LICENSE ├── Model_Examples ├── data.scale ├── data.scale.model.linear ├── data.scale.model.poly ├── data.scale.model.rbf ├── data.scale.model.sig ├── data.txt ├── linear │ └── sketch_svm │ │ ├── linear_kernel.ino │ │ ├── measurement.ino │ │ ├── sketch_svm.ino │ │ └── svm_evaluate.ino ├── poly │ └── sketch_svm │ │ ├── measurement.ino │ │ ├── polynomial_kernel.ino │ │ ├── sketch_svm.ino │ │ └── svm_evaluate.ino ├── range ├── rbf │ └── sketch_svm │ │ ├── measurement.ino │ │ ├── rbf_kernel.ino │ │ ├── sketch_svm.ino │ │ └── svm_evaluate.ino └── sig │ └── sketch_svm │ ├── measurement.ino │ ├── sigmoid_kernel.ino │ ├── sketch_svm.ino │ └── svm_evaluate.ino ├── README.md └── rbf_example └── sketch_svm ├── measurement.ino ├── rbf_kernel.ino ├── sketch_svm.ino └── svm_evaluate.ino /Arduino_SVM/Arduino_SVM.pde: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import controlP5.*; 3 | import processing.serial.*; 4 | 5 | Serial serial; 6 | PrintWriter output; 7 | 8 | Textfield modelFileName; 9 | Textfield scalingFileName; 10 | Textfield outputFileName; 11 | Textlabel text; 12 | 13 | ControlP5 controlP5; 14 | 15 | Button start; 16 | Button close; 17 | 18 | // variables to save the information from the model and the scaling document 19 | String kernelType; 20 | String[] modelData; 21 | String[] scalingData; 22 | String[] range; 23 | String[] scale = new String[3]; 24 | String model = ""; 25 | int nr_sens = 0; 26 | int nr_class; 27 | int[] nr_sv; 28 | 29 | String[] split; 30 | StringList highRange = new StringList(); 31 | StringList lowRange = new StringList(); 32 | 33 | // setup the window 34 | void setup() { 35 | size(300, 300); 36 | smooth(); 37 | background(0, 0, 0); 38 | 39 | controlP5 = new ControlP5(this); 40 | 41 | modelFileName = controlP5.addTextfield("Model Path", 10, 10, 200, 20); 42 | modelFileName.setText(""); 43 | scalingFileName = controlP5.addTextfield("Scaling Path", 10, 50, 200, 20); 44 | scalingFileName.setText(""); 45 | outputFileName = controlP5.addTextfield("Output Folder Path", 10, 150, 200, 20); 46 | outputFileName.setText(""); 47 | 48 | text = controlP5.addTextlabel("Text", "Please insert Files", 10, 100); 49 | 50 | 51 | stroke(255); 52 | line(10, 240, 290, 240); 53 | 54 | start = controlP5.addButton("Start", 150, 160, 260, 60, 20); 55 | close = controlP5.addButton("Close", 150, 230, 260, 60, 20); 56 | } 57 | void draw() { 58 | } 59 | // controleEvent is triggered by start and close buttons 60 | // if start is pressed a new Arduino Sketch is created from the model and the scaling range 61 | // if close is pressed the window is closed 62 | void controlEvent(ControlEvent theEvent) { 63 | if (theEvent.isFrom(start)) { 64 | 65 | // creation of the output file writer and the input file readers 66 | output = createWriter( outputFileName.getText()+"/sketch_svm/sketch_svm.ino" ); 67 | modelData = loadStrings(modelFileName.getText()); 68 | scalingData = loadStrings(scalingFileName.getText()); 69 | 70 | if (modelData == null || scalingData == null) { 71 | fill(0, 0, 0); 72 | stroke (0); 73 | rect(10, 100, 200, 45); 74 | text.setText("Please insert correct paths"); 75 | return; 76 | } 77 | 78 | // test if the correct kind of model is loaded 79 | split = split(modelData[0], " "); 80 | if (!split[0].equals("svm_type")) { 81 | fill(0, 0, 0); 82 | stroke (0); 83 | rect(10, 100, 200, 45); 84 | text.setText("Please insert a model file path"); 85 | return; 86 | } else if (!split[1].equals("c_svc")) { 87 | fill(0, 0, 0); 88 | stroke (0); 89 | rect(10, 100, 200, 45); 90 | text.setText("Please insert a c_svc model"); 91 | return; 92 | } else { 93 | split = split(modelData[1], " "); 94 | 95 | if (!(split[1].equals("polynomial")||split[1].equals("linear")||split[1].equals("rbf")||split[1].equals("sigmoid"))) { 96 | fill(0, 0, 0); 97 | stroke(0); 98 | rect(10, 100, 200, 45); 99 | text.setText("Please insert a model with one of the following kernels:\npolynomial, linear, rbf, sigmoid"); 100 | return; 101 | } 102 | 103 | split = split(scalingData[0], " "); 104 | 105 | // test if the correct kind of scaling file is loaded 106 | if (!split[0].equals("x")) { 107 | fill(0, 0, 0); 108 | stroke(0); 109 | rect(10, 100, 200, 45); 110 | text.setText("Please insert a scaling file path"); 111 | return; 112 | } 113 | 114 | 115 | // create the Arduino sketch from the model and scaling parameters 116 | boolean sv = false; 117 | output.println("#include "); 118 | // for every line of the model file read the information and create the Arduino sketch 119 | for (int i = 0; i < modelData.length; i++) { 120 | 121 | split = split(modelData[i], " "); 122 | // if the section with SV's is already reached start to save the SV's and Yalphas 123 | if (sv) { 124 | 125 | int x = 0; 126 | int start = i; 127 | 128 | while (x < nr_sv.length) { 129 | String[] yalpha = new String[nr_sv.length - 1]; 130 | String[] svs = new String[nr_sv[x]]; 131 | 132 | for (int r = 0; r< yalpha.length; r++) { 133 | yalpha[r] = ""; 134 | } 135 | for (int r = 0; r< svs.length; r++) { 136 | svs[r] = ""; 137 | } 138 | for (int y = start; y < start + nr_sv[x]; y++) { 139 | split = split(modelData[y], " "); 140 | int nr = 1; 141 | 142 | for (int j = 0; j < yalpha.length; j++) { 143 | if (j == yalpha.length-1 && y == start + nr_sv[x]-1) { 144 | yalpha[j] = yalpha[j] +split[j]; 145 | } else { 146 | yalpha[j] = yalpha[j] +split[j] + ", "; 147 | } 148 | } 149 | for (int j = yalpha.length; j < split.length-1; j++) { 150 | String[] part = split(split[j], ":"); 151 | if (j == split.length-2 && y == start + nr_sv[x]-1) { 152 | while (nr < int (part[0]) ) { 153 | svs[y-start] = svs[y-start] + "0"; 154 | nr++; 155 | } 156 | svs[y-start] = svs[y-start] + split(split[j], ":")[part.length -1]; 157 | nr++; 158 | } else { 159 | while (nr < int (part[0]) ) { 160 | svs[y-start] = svs[y-start] + "0" + ", "; 161 | nr++; 162 | } 163 | svs[y-start] = svs[y-start] + split(split[j], ":")[part.length -1] + ", " ; 164 | nr++; 165 | } 166 | } 167 | if (nr > nr_sens) { 168 | nr_sens = nr-1; 169 | } 170 | } 171 | model = model + "\n const PROGMEM float yalpha"+str(x+1)+"["+str(nr_sv[x])+" * (NR_CLASS-1)] = {"; 172 | for (int t = 0; t < yalpha.length; t++) { 173 | model = model + yalpha[t]; 174 | } 175 | model = model + "}; \n"; 176 | model = model + "\n const PROGMEM float sv"+str(x+1)+"["+str(nr_sv[x])+" * VEC_DIM] = {"; 177 | for (int p = 0; p < svs.length; p++) { 178 | 179 | model = model + svs[p]; 180 | } 181 | model = model + "}; \n"; 182 | 183 | start = start + nr_sv[x]; 184 | x++; 185 | } 186 | output.println("#define VEC_DIM " + str(nr_sens)); 187 | break; 188 | // as long as the SV section is not reached read out the other data 189 | } else { 190 | if (split.length > 2) { 191 | if (split[0].equals("rho")) { 192 | model = model + "\n" + "const PROGMEM float " + split[0]+"[]" + " = {"; 193 | } else { 194 | model = model + "\n" + "const int " + split[0]+"[]" + " = {"; 195 | } 196 | if (split[0].equals("nr_sv")) { 197 | for (int j = 1; j < split.length; j++) { 198 | nr_sv[j-1] = int(split[j]); 199 | } 200 | } 201 | for (int j = 1; j < split.length; j++) { 202 | if (j == split.length -1) { 203 | model = model + split[j] + "};"; 204 | } else { 205 | model = model + split[j] + ", "; 206 | } 207 | } 208 | } else if (!split[0].equals("SV")) { 209 | if (split[0].equals("nr_class")) { 210 | nr_class = int(split[1]); 211 | nr_sv = new int[nr_class]; 212 | } 213 | if (split[0].equals("gamma")) { 214 | model = model + "\n" + "#define GAMMA " + split[1]; 215 | } 216 | if (split[0].equals("rho")) { 217 | model = model + "\n" + "const PROGMEM float " + split[0]+"[]" + " = {" + split[1] + "};"; 218 | } 219 | if (split[0].equals("nr_class")) { 220 | model = model + "\n" + "#define NR_CLASS " + split[1]; 221 | } 222 | if (split[0].equals("total_sv")) { 223 | model = model + "\n" + "#define TOTAL_SV " + split[1]; 224 | } 225 | if (split[0].equals("degree")) { 226 | model = model + "\n" + "#define DEGREE " + split[1]; 227 | } 228 | if (split[0].equals("coef0")) { 229 | model = model + "\n" + "#define COEF0 " + split[1]; 230 | } 231 | if (split[0].equals("svm_type")) { 232 | model = model + "\n" + "#define SVM_TYPE " + split[1] ; 233 | } 234 | if (split[0].equals("kernel_type")) { 235 | kernelType = split[1]; 236 | model = model + "\n" + "#define KERNEL_TYPE " + split[1] ; 237 | } 238 | if (split[0].equals("nr_sv")) { 239 | for (int j = 1; j < split.length; j++) { 240 | nr_sv[j-1] = int(split[j]); 241 | } 242 | } 243 | if (split[0].equals("nr_sv")||split[0].equals("label")) { 244 | model = model + "\n" + "const int " + split[0]+"[]" + " = {" + split[1] + "};"; 245 | } 246 | } else { 247 | sv = true; 248 | } 249 | } 250 | } 251 | 252 | // output the information of the model into the Arduino sketch 253 | output.println(model); 254 | // read in the scaling parameters 255 | for (int i = 0; i < scalingData.length; i++) { 256 | if (i == 1) { 257 | range = split(scalingData[i], " "); 258 | scale[0] = "const int scalePar[] = {"+range[0]+","+range[1]+"};"; 259 | scale[1] = "const int low[] = {"; 260 | scale[2] = "const int high[] = {"; 261 | } else if (i > 1) { 262 | split = split(scalingData[i], " "); 263 | 264 | if (i == scalingData.length -1) { 265 | scale[1]= scale[1]+ split[1] + "};"; 266 | scale[2]= scale[2]+ split[2] + "}; "; 267 | } else { 268 | scale[1]= scale[1]+ split[1] + ","; 269 | scale[2]= scale[2]+ split[2] + ","; 270 | } 271 | } 272 | } 273 | // output the scaling parameters 274 | for (int i = 0; i 0) {\n result[i]++;\n } else {\n result[j]++;\n }\n rhoCounter++;\n }\n }"); 300 | output.println("\n\n int temp = 0;\n for(int t = 0; t < NR_CLASS; t++){\n if(result[temp] <= result[t]){\n recognizedClass = t;\n temp = t;\n }\n }"); 301 | output.println("\n\n Serial.println(recognizedClass, DEC);\n delay(500);\n for(int q = 0; q < NR_CLASS; q++){\n result[q]=0;\n }\n}"); 302 | output.flush(); 303 | output.close(); 304 | // selection of the used kernel class 305 | if (kernelType.equals("linear")) { 306 | output = createWriter( outputFileName.getText()+"/sketch_svm/linear_kernel.ino" ); 307 | output.println("#ifndef VEC_DIM\n#error \n#endif\n\n#include \n\ninline float linear_kernel(float* u, float* v){\n float result=0;\n for (int j=0; j\n\n // In this section you should implement the handling of your sensor data, which you would like to classify.\n // and an example would be:\nint sensors[5] = {0}; "); 314 | output.println("\n// int sensor1, sensor2, sensor3, sensor4, sensor5;"); 315 | output.println("\n void setup(){\n Serial.begin(115200);\n}"); 316 | output.println("\nvoid loop(){"); 317 | output.println("\n //sensor1 = analogRead(0);\n //sensor2 = analogRead(1);\n //sensor3 = analogRead(2);\n //sensor4 = analogRead(3);\n //sensor5 = analogRead(4);\n //delay(600);\n // sensors= {sensor1, sensor2, sensor3, sensor4, sensor5};"); 318 | output.println("\n svm_predict(sensors);\n}"); 319 | output.flush(); 320 | output.close(); 321 | if (kernelType.equals("polynomial")) { 322 | output = createWriter( outputFileName.getText()+"/sketch_svm/polynomial_kernel.ino" ); 323 | output.println("#ifndef VEC_DIM\n#error\n#endif\n\n#ifndef GAMMA\n#error\n#endif\n\n#ifndef COEF0\n#error\n#endif\n\n#ifndef DEGREE\n#error\n#endif\n\n#include \n"); 324 | output.println("inline float polynomial_kernel(float* u, float* v){\n float result=0;\n\n for (int j=0; j"); 332 | output.println("\ninline float rbf_kernel(float* u, float* v){\n float result=0;\n for (int j=0; j\n\n"); 340 | output.println("inline float sigmoid_kernel(float* u, float* v){\n float result=0;\n for (int j=0; j\n\n"); 348 | output.println("inline float svm_evaluate(int n_sv, float* coeffs, float* sv_class, float* sensors){\n float result= 0;\n float* sv_current = sv_class;\n for (int i=0; i 6 | 7 | inline float linear_kernel(float* u, float* v){ 8 | float result=0; 9 | for (int j=0; j 2 | 3 | // In this section you should implement the handling of your sensor data, which you would like to classify. 4 | // and an example would be: 5 | int sensors[5] = {0}; 6 | 7 | // int sensor1, sensor2, sensor3, sensor4, sensor5; 8 | 9 | void setup(){ 10 | Serial.begin(115200); 11 | } 12 | 13 | void loop(){ 14 | 15 | //sensor1 = analogRead(0); 16 | //sensor2 = analogRead(1); 17 | //sensor3 = analogRead(2); 18 | //sensor4 = analogRead(3); 19 | //sensor5 = analogRead(4); 20 | //delay(600); 21 | // sensors= {sensor1, sensor2, sensor3, sensor4, sensor5}; 22 | 23 | svm_predict(sensors); 24 | } 25 | -------------------------------------------------------------------------------- /Model_Examples/linear/sketch_svm/sketch_svm.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #define VEC_DIM 9 3 | 4 | #define SVM_TYPE c_svc 5 | #define KERNEL_TYPE linear 6 | #define NR_CLASS 5 7 | #define TOTAL_SV 27 8 | const PROGMEM float rho[] = {1.06877, 0.342367, 0.271674, 0.213677, 0.266449, 0.0492231, -0.0669559, -0.0928679, -0.121012, -0.0884864}; 9 | const int label[] = {0, 1, 2, 3, 4}; 10 | const int nr_sv[] = {4, 5, 5, 6, 7}; 11 | const PROGMEM float yalpha1[4 * (NR_CLASS-1)] = {1, 0.4595338242000765, 0.09042252171083272, 0.1409934987286733, 0.4038454100020114, 0, 0, 0, 0.2984824651311233, 0, 0, 0.004575003591770739, 0.3953786137021565, 0, 0, 0}; 12 | 13 | const PROGMEM float sv1[4 * VEC_DIM] = {0.114754, 0.583333, 0.676768, 0.676768, 0.547826, 0.622222, 0.655172, 0.666667, 0.52381, 0.0983607, 0.791667, 0.79798, 0.717172, 0.6, 0.555556, 0.741379, 0.716667, 0.790476, 0.0983607, 0.861111, 0.959596, 0.818182, 0.617391, 0.488889, 0.689655, 0.65, 0.67619, 0.0655738, 0.819444, 0.818182, 0.272727, 0.6, 0.6, 0.568966, 0.75, 0.942857}; 14 | 15 | const PROGMEM float yalpha2[5 * (NR_CLASS-1)] = {0.1409934987286733, -1, -0, -0, -0, 0, 0.155522919475877, 0.495803341431051, 0.4103022248912957, 0, 0.004575003591770739, 0, 0.2535540469784882, 0.3513327743977417, 0, 0, 0.006975830730241244, 0, 0.6426082815307304, 0.09507369987874643}; 16 | 17 | const PROGMEM float sv2[5 * VEC_DIM] = {0.0655738, 0.819444, 0.818182, 0.272727, 0.6, 0.6, 0.568966, 0.75, 0.942857, 0.213115, 0.194444, 0.292929, 0.515152, 0.86087, 0.688889, 0.327586, 0.55, 0.333333, 0, -0.263889, 0.636364, 0.636364, 0.756522, 0.488889, 0.310345, -0.45, 0.580952, 0.131148, 0.0555556, 0.0707071, 0.353535, 0.86087, 0.377778, 0.327586, -0.45, 0.657143, 0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524}; 18 | 19 | const PROGMEM float yalpha3[5 * (NR_CLASS-1)] = {-0, -0.6909498446395825, -0.2015992786081303, -0.202246131393881, -0, 0, 0, -0.2363907409795529, -0.8252377448186706, -0, 0, 0, 0, 0.6731601105465157, 0.2091048705441852, 0.09507369987874643, 0, 0, 0.1250702524419036, 0}; 20 | 21 | const PROGMEM float sv3[5 * VEC_DIM] = {0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524, 0.180328, 0.138889, 0.757576, 0.818182, 0.791304, 0.488889, 0.362069, -0.45, 0.638095, 0.0327869, -0.555556, -0.292929, 0.555556, 0.617391, 0.466667, -0.551724, -0.216667, -0.180952, -0.0327869, -0.569444, 0.0707071, 0.272727, 0.478261, 0.355556, -0.603448, -0.35, -0.142857, -0.114754, -0.0277778, -0.79798, 0.373737, 0.513043, -0.266667, -0.517241, -0.883333, -0.828571}; 22 | 23 | const PROGMEM float yalpha4[6 * (NR_CLASS-1)] = {-0, -0, -0, -0, -0, -0.08905226987839665, -0, -0, -0, -0, -0, -0, 0.2091048705441852, 0, 0.4839038273863283, -0, -0, -0, 0, 0.6666791314585784, 0, 0.3402761989129244, 0.008464052645961149, 0}; 24 | 25 | const PROGMEM float sv4[6 * VEC_DIM] = {-0.114754, -0.0277778, -0.79798, 0.373737, 0.513043, -0.266667, -0.517241, -0.883333, -0.828571, 0.147541, -0.541667, -0.717172, 0.313131, 0.46087, 0.111111, -0.482759, -0.583333, -0.638095, -0.0983607, -0.847222, -0.89899, -0.414141, 0.391304, 0.111111, -0.931034, -0.833333, -0.390476, -0.836066, -0.625, -0.272727, -0.131313, -0.00869565, -0.955556, 0, -0.2, -0.447619, -0.459016, -0.513889, -0.292929, -0.79798, -1, -0.777778, -0.448276, -0.233333, 0.0666667, -0.819672, -0.263889, -0.212121, 0.111111, -0.513043, -0.355556, -0.689655, 0.116667, -0.295238}; 26 | 27 | const PROGMEM float yalpha5[7 * (NR_CLASS-1)] = {-0.08905226987839665, -0, -0, -0.2140051988444974, -0, -0.1425526046921795, -0, -0, -0, -0, -0.60488682137623, -0, -0.6805762878534299, -0.06408152428628813, -0, -0.3086904450467835, -0.5416113500373424, -0.5158670133929035, -0.4099632938523962, -0, -0, 0, 0, 0.1701505855375848, 0.162213004180823, -0.008755626905906141, -0, -0.4191847453003477}; 28 | 29 | const PROGMEM float sv5[7 * VEC_DIM] = {-0.819672, -0.263889, -0.212121, 0.111111, -0.513043, -0.355556, -0.689655, 0.116667, -0.295238, -1, -1, -0.79798, -0.454545, -0.321739, -0.622222, -0.62069, -0.383333, -0.447619, -0.459016, -0.222222, 0.252525, -0.313131, -0.2, -0.422222, -0.896552, -0.65, -1, -0.557377, -0.402778, 0.373737, -0.353535, 0.0608696, -0.444444, -0.551724, -0.5, 0.466667, 0.508197, -0.583333, -0.515152, -0.636364, 0.408696, -0.0888889, 0.793103, -0.5, -0.67619, 0.57377, 0.319444, -0.252525, -0.515152, 0.373913, 0.422222, 0.603448, -0.666667, -0.447619, 0.278689, 0.180556, 0.030303, -0.373737, 0.356522, -0.577778, 0.862069, -0.7, -0.619048}; 30 | 31 | const int scalePar[] = {-1,1}; 32 | const int low[] = {517,544,543,546,733,576,552,526,552}; 33 | const int high[] = {639,688,642,645,848,666,668,646,657}; 34 | int result[NR_CLASS]={0}; 35 | 36 | float const* const supportVectors[NR_CLASS] PROGMEM = { 37 | sv1, sv2, sv3, sv4, sv5, }; 38 | const float* const valuesForSupport[NR_CLASS] PROGMEM = { 39 | yalpha1, yalpha2, yalpha3, yalpha4, yalpha5, }; 40 | 41 | void scale(const int* sensor, float* scaledSensor){ 42 | for(int p=0; p 0) { 74 | result[i]++; 75 | } else { 76 | result[j]++; 77 | } 78 | rhoCounter++; 79 | } 80 | } 81 | 82 | 83 | int temp = 0; 84 | for(int t = 0; t < NR_CLASS; t++){ 85 | if(result[temp] <= result[t]){ 86 | recognizedClass = t; 87 | temp = t; 88 | } 89 | } 90 | 91 | 92 | Serial.println(recognizedClass, DEC); 93 | delay(500); 94 | for(int q = 0; q < NR_CLASS; q++){ 95 | result[q]=0; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Model_Examples/linear/sketch_svm/svm_evaluate.ino: -------------------------------------------------------------------------------- 1 | #ifndef VEC_DIM 2 | #error 3 | #endif 4 | 5 | #include 6 | 7 | 8 | inline float svm_evaluate(int n_sv, float* coeffs, float* sv_class, float* sensors){ 9 | float result= 0; 10 | float* sv_current = sv_class; 11 | for (int i=0; i 2 | 3 | // In this section you should implement the handling of your sensor data, which you would like to classify. 4 | // and an example would be: 5 | int sensors[5] = {0}; 6 | 7 | // int sensor1, sensor2, sensor3, sensor4, sensor5; 8 | 9 | void setup(){ 10 | Serial.begin(115200); 11 | } 12 | 13 | void loop(){ 14 | 15 | //sensor1 = analogRead(0); 16 | //sensor2 = analogRead(1); 17 | //sensor3 = analogRead(2); 18 | //sensor4 = analogRead(3); 19 | //sensor5 = analogRead(4); 20 | //delay(600); 21 | // sensors= {sensor1, sensor2, sensor3, sensor4, sensor5}; 22 | 23 | svm_predict(sensors); 24 | } 25 | -------------------------------------------------------------------------------- /Model_Examples/poly/sketch_svm/polynomial_kernel.ino: -------------------------------------------------------------------------------- 1 | #ifndef VEC_DIM 2 | #error 3 | #endif 4 | 5 | #ifndef GAMMA 6 | #error 7 | #endif 8 | 9 | #ifndef COEF0 10 | #error 11 | #endif 12 | 13 | #ifndef DEGREE 14 | #error 15 | #endif 16 | 17 | #include 18 | 19 | inline float polynomial_kernel(float* u, float* v){ 20 | float result=0; 21 | 22 | for (int j=0; j 2 | #define VEC_DIM 9 3 | 4 | #define SVM_TYPE c_svc 5 | #define KERNEL_TYPE polynomial 6 | #define DEGREE 3 7 | #define GAMMA 0.111111 8 | #define COEF0 0 9 | #define NR_CLASS 5 10 | #define TOTAL_SV 50 11 | const PROGMEM float rho[] = {0.433865, 0.326431, 0.196373, 0.320688, 0.00433523, -0.079755, -0.0990719, -0.0673645, -0.107552, -0.0543994}; 12 | const int label[] = {0, 1, 2, 3, 4}; 13 | const int nr_sv[] = {10, 10, 10, 10, 10}; 14 | const PROGMEM float yalpha1[10 * (NR_CLASS-1)] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 15 | 16 | const PROGMEM float sv1[10 * VEC_DIM] = {0.114754, 0.583333, 0.676768, 0.676768, 0.547826, 0.622222, 0.655172, 0.666667, 0.52381, 0.0983607, 0.791667, 0.79798, 0.717172, 0.6, 0.555556, 0.741379, 0.716667, 0.790476, 0.0983607, 0.861111, 0.959596, 0.818182, 0.617391, 0.488889, 0.689655, 0.65, 0.67619, 0.0819672, 0.805556, 1, 0.494949, 0.478261, 0.511111, 0.62069, 0.816667, 1, 0.147541, 0.902778, 0.919192, 0.515152, 0.617391, 0.511111, 0.603448, 0.766667, 0.92381, 0.0655738, 0.819444, 0.818182, 0.272727, 0.6, 0.6, 0.568966, 0.75, 0.942857, -0.0819672, 1, 0.959596, 0.434343, 0.513043, 0.533333, 0.534483, 0.766667, 1, 0.0819672, 0.75, 0.919192, 0.59596, 0.513043, 0.555556, 0.517241, 0.766667, 0.885714, 0.196721, 0.694444, 1, 0.555556, 0.46087, 0.533333, 0.551724, 1, 1, 0.213115, 0.847222, 0.919192, 0.616162, 0.46087, 0.711111, 0.431034, 0.85, 0.980952}; 17 | 18 | const PROGMEM float yalpha2[10 * (NR_CLASS-1)] = {1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 19 | 20 | const PROGMEM float sv2[10 * VEC_DIM] = {0.213115, 0.847222, 0.919192, 0.616162, 0.46087, 0.711111, 0.431034, 0.85, 0.980952, 0.47541, 0.0416667, 0.212121, 0.838384, 0.878261, 0.844444, 0.327586, -0.533333, 0.657143, 0.42623, 0.0972222, 0.353535, 0.959596, 0.773913, 0.688889, 0.362069, -0.483333, 0.638095, 0.213115, 0.194444, 0.292929, 0.515152, 0.86087, 0.688889, 0.327586, 0.55, 0.333333, 0.0327869, -0.111111, 0.616162, 0.757576, 0.791304, 0.488889, 0.310345, -0.5, 0.561905, 0, -0.263889, 0.636364, 0.636364, 0.756522, 0.488889, 0.310345, -0.45, 0.580952, 0.131148, 0.0555556, 0.0707071, 0.353535, 0.86087, 0.377778, 0.327586, -0.45, 0.657143, 0.311475, 0.194444, 0.272727, 0.575758, 0.913043, 0.844444, 0.0862069, -0.4, 0.6, 0.180328, -0.166667, -0.0909091, 0.515152, 0.86087, 0.488889, 0.517241, -0.316667, 0.714286, 0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524}; 21 | 22 | const PROGMEM float yalpha3[10 * (NR_CLASS-1)] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 23 | 24 | const PROGMEM float sv3[10 * VEC_DIM] = {0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524, 0.180328, 0.138889, 0.757576, 0.818182, 0.791304, 0.488889, 0.362069, -0.45, 0.638095, 0.0327869, -0.555556, -0.292929, 0.555556, 0.617391, 0.466667, -0.551724, -0.216667, -0.180952, -0.0327869, -0.569444, 0.0707071, 0.272727, 0.478261, 0.355556, -0.603448, -0.35, -0.142857, -0.114754, -0.0277778, -0.79798, 0.373737, 0.513043, -0.266667, -0.517241, -0.883333, -0.828571, 0.147541, -0.541667, -0.717172, 0.313131, 0.46087, 0.111111, -0.482759, -0.583333, -0.638095, -0.0163934, -0.930556, -1, 0.292929, 0.443478, 0.2, -0.775862, -0.566667, -0.104762, -0.229508, -0.916667, -0.676768, 0.212121, 0.530435, 0.444444, -0.637931, -0.583333, -0.0666667, -0.327869, -0.847222, -0.313131, 0.656566, 0.530435, 0.266667, -0.465517, -0.55, -0.0666667, -0.0983607, -0.847222, -0.89899, -0.414141, 0.391304, 0.111111, -0.931034, -0.833333, -0.390476}; 25 | 26 | const PROGMEM float yalpha4[10 * (NR_CLASS-1)] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 27 | 28 | const PROGMEM float sv4[10 * VEC_DIM] = {-0.0983607, -0.847222, -0.89899, -0.414141, 0.391304, 0.111111, -0.931034, -0.833333, -0.390476, -0.196721, -0.875, -0.252525, 1, 0.582609, 0.155556, -0.982759, -0.733333, -0.047619, 0, -0.472222, -0.858586, 0.656566, 0.408696, -0.422222, -1, -0.6, -0.714286, -0.885246, -0.638889, -0.474747, -0.353535, -0.252174, -0.933333, -0.137931, -0.45, -0.542857, -0.836066, -0.625, -0.272727, -0.131313, -0.00869565, -0.955556, 0, -0.2, -0.447619, -0.52459, -0.361111, -0.171717, -1, -1, -0.933333, -0.689655, -0.45, 0.0857143, -0.459016, -0.513889, -0.292929, -0.79798, -1, -0.777778, -0.448276, -0.233333, 0.0666667, -0.918033, -0.513889, -0.373737, -0.292929, -0.321739, -0.466667, -0.517241, 0.166667, -0.504762, -0.819672, -0.263889, -0.212121, 0.111111, -0.513043, -0.355556, -0.689655, 0.116667, -0.295238, -0.918033, -0.944444, -0.414141, -0.69697, -0.217391, -1, -0.534483, -0.516667, -0.561905}; 29 | 30 | const PROGMEM float yalpha5[10 * (NR_CLASS-1)] = {-0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1}; 31 | 32 | const PROGMEM float sv5[10 * VEC_DIM] = {-0.918033, -0.944444, -0.414141, -0.69697, -0.217391, -1, -0.534483, -0.516667, -0.561905, -1, -1, -0.79798, -0.454545, -0.321739, -0.622222, -0.62069, -0.383333, -0.447619, -0.459016, -0.222222, 0.252525, -0.313131, -0.2, -0.422222, -0.896552, -0.65, -1, -0.557377, -0.402778, 0.373737, -0.353535, 0.0608696, -0.444444, -0.551724, -0.5, 0.466667, 0.508197, -0.583333, -0.515152, -0.636364, 0.408696, -0.0888889, 0.793103, -0.5, -0.67619, 0.622951, 0.583333, -0.030303, -0.292929, -0.026087, 0.866667, 0.706897, -0.916667, -0.771429, 1, 0.291667, -0.0909091, -0.717172, 1, 1, 0.62069, -0.966667, -0.6, 0.57377, 0.319444, -0.252525, -0.515152, 0.373913, 0.422222, 0.603448, -0.666667, -0.447619, 0.278689, 0.180556, 0.030303, -0.373737, 0.356522, -0.577778, 0.862069, -0.7, -0.619048, 0.459016, -0.0972222, -0.232323, -0.757576, -0.113043, 0.0666667, 0.965517, -0.416667, -0.352381}; 33 | 34 | const int scalePar[] = {-1,1}; 35 | const int low[] = {517,544,543,546,733,576,552,526,552}; 36 | const int high[] = {639,688,642,645,848,666,668,646,657}; 37 | int result[NR_CLASS]={0}; 38 | 39 | float const* const supportVectors[NR_CLASS] PROGMEM = { 40 | sv1, sv2, sv3, sv4, sv5, }; 41 | const float* const valuesForSupport[NR_CLASS] PROGMEM = { 42 | yalpha1, yalpha2, yalpha3, yalpha4, yalpha5, }; 43 | 44 | void scale(const int* sensor, float* scaledSensor){ 45 | for(int p=0; p 0) { 77 | result[i]++; 78 | } else { 79 | result[j]++; 80 | } 81 | rhoCounter++; 82 | } 83 | } 84 | 85 | 86 | int temp = 0; 87 | for(int t = 0; t < NR_CLASS; t++){ 88 | if(result[temp] <= result[t]){ 89 | recognizedClass = t; 90 | temp = t; 91 | } 92 | } 93 | 94 | 95 | Serial.println(recognizedClass, DEC); 96 | delay(500); 97 | for(int q = 0; q < NR_CLASS; q++){ 98 | result[q]=0; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Model_Examples/poly/sketch_svm/svm_evaluate.ino: -------------------------------------------------------------------------------- 1 | #ifndef VEC_DIM 2 | #error 3 | #endif 4 | 5 | #include 6 | 7 | 8 | inline float svm_evaluate(int n_sv, float* coeffs, float* sv_class, float* sensors){ 9 | float result= 0; 10 | float* sv_current = sv_class; 11 | for (int i=0; i 2 | 3 | // In this section you should implement the handling of your sensor data, which you would like to classify. 4 | // and an example would be: 5 | int sensors[5] = {0}; 6 | 7 | // int sensor1, sensor2, sensor3, sensor4, sensor5; 8 | 9 | void setup(){ 10 | Serial.begin(115200); 11 | } 12 | 13 | void loop(){ 14 | 15 | //sensor1 = analogRead(0); 16 | //sensor2 = analogRead(1); 17 | //sensor3 = analogRead(2); 18 | //sensor4 = analogRead(3); 19 | //sensor5 = analogRead(4); 20 | //delay(600); 21 | // sensors= {sensor1, sensor2, sensor3, sensor4, sensor5}; 22 | 23 | svm_predict(sensors); 24 | } 25 | -------------------------------------------------------------------------------- /Model_Examples/rbf/sketch_svm/rbf_kernel.ino: -------------------------------------------------------------------------------- 1 | #ifndef VEC_DIM 2 | #error 3 | #endif 4 | 5 | #ifndef GAMMA 6 | #error 7 | #endif 8 | 9 | #include 10 | 11 | inline float rbf_kernel(float* u, float* v){ 12 | float result=0; 13 | for (int j=0; j 2 | #define VEC_DIM 9 3 | 4 | #define SVM_TYPE c_svc 5 | #define KERNEL_TYPE rbf 6 | #define GAMMA 1 7 | #define NR_CLASS 5 8 | #define TOTAL_SV 34 9 | const PROGMEM float rho[] = {0.36276, 0.371906, 0.473969, 0.451522, 0.137938, 0.25699, 0.231955, 0.142067, 0.0977635, -0.0295956}; 10 | const int label[] = {0, 1, 2, 3, 4}; 11 | const int nr_sv[] = {5, 6, 8, 8, 7}; 12 | const PROGMEM float yalpha1[5 * (NR_CLASS-1)] = {2.107335316049639, 0, 0.2964265104934171, 0.2295626192109151, 0.05271834980593445, 0.732576868565294, 0.1003888070674556, 0, 0.5958535967753404, 0.3937788597496962, 0.7819447269800799, 0.1095371855556466, 0, 0.6412513842416325, 0.4244461486714203, 0.7736147721476789, 0.1085783037267564, 0, 0.629383488716891, 0.4167085121221615}; 13 | 14 | const PROGMEM float sv1[5 * VEC_DIM] = {0.114754, 0.583333, 0.676768, 0.676768, 0.547826, 0.622222, 0.655172, 0.666667, 0.52381, 0.0983607, 0.861111, 0.959596, 0.818182, 0.617391, 0.488889, 0.689655, 0.65, 0.67619, 0.0655738, 0.819444, 0.818182, 0.272727, 0.6, 0.6, 0.568966, 0.75, 0.942857, -0.0819672, 1, 0.959596, 0.434343, 0.513043, 0.533333, 0.534483, 0.766667, 1, 0.196721, 0.694444, 1, 0.555556, 0.46087, 0.533333, 0.551724, 1, 1}; 15 | 16 | const PROGMEM float yalpha2[6 * (NR_CLASS-1)] = {0.05271834980593445, -0, -1.736859881676639, -0, -0, -0.3689736056802617, 0.3937788597496962, 0.2591110144046342, 0.8367291914326392, 0.6725956776744122, 0.03482470347779317, 0.7436913873588609, 0.4244461486714203, 0.2646118216882179, 0.8944199942693069, 0.581171811381979, 0.01491533353693937, 0.8116112072253026, 0.4167085121221615, 0.260659683970744, 0.8813026753556298, 0.542198226750192, 0.03873916724600095, 0.8058610806097716}; 17 | 18 | const PROGMEM float sv2[6 * VEC_DIM] = {0.196721, 0.694444, 1, 0.555556, 0.46087, 0.533333, 0.551724, 1, 1, 0.47541, 0.0416667, 0.212121, 0.838384, 0.878261, 0.844444, 0.327586, -0.533333, 0.657143, 0.213115, 0.194444, 0.292929, 0.515152, 0.86087, 0.688889, 0.327586, 0.55, 0.333333, 0, -0.263889, 0.636364, 0.636364, 0.756522, 0.488889, 0.310345, -0.45, 0.580952, 0.180328, -0.166667, -0.0909091, 0.515152, 0.86087, 0.488889, 0.517241, -0.316667, 0.714286, 0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524}; 19 | 20 | const PROGMEM float yalpha3[8 * (NR_CLASS-1)] = {-0.3689736056802617, -0.580209308203005, -0.1093331482812802, -0.2916458132181204, -0.3582523908090453, -0.07469041930962894, -0, -0.4159890905458756, 0.7436913873588609, 0.09481529177328665, -0.2795322611114798, -0.5077933408456813, -0.4876216582817534, -0.05530164919925538, -0, -0.5712516571134669, 0.8116112072253026, 0.2223914172017729, 0, 0.8614699454524755, 0.7287595824479804, 0.114259993040315, 0.01592139013398465, 0.8852447089321018, 0.8058610806097716, 0.2295852587515451, 0.1677228201223715, 0.5573917025217557, 0.6785914797644198, 0.1349397367869411, 0, 0.7398007723265512}; 21 | 22 | const PROGMEM float sv3[8 * VEC_DIM] = {0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524, 0.180328, 0.138889, 0.757576, 0.818182, 0.791304, 0.488889, 0.362069, -0.45, 0.638095, 0.0327869, -0.555556, -0.292929, 0.555556, 0.617391, 0.466667, -0.551724, -0.216667, -0.180952, -0.0327869, -0.569444, 0.0707071, 0.272727, 0.478261, 0.355556, -0.603448, -0.35, -0.142857, -0.114754, -0.0277778, -0.79798, 0.373737, 0.513043, -0.266667, -0.517241, -0.883333, -0.828571, -0.0163934, -0.930556, -1, 0.292929, 0.443478, 0.2, -0.775862, -0.566667, -0.104762, -0.327869, -0.847222, -0.313131, 0.656566, 0.530435, 0.266667, -0.465517, -0.55, -0.0666667, -0.0983607, -0.847222, -0.89899, -0.414141, 0.391304, 0.111111, -0.931034, -0.833333, -0.390476}; 23 | 24 | const PROGMEM float yalpha4[8 * (NR_CLASS-1)] = {-0.4159890905458756, -0.3557046763627751, -0.2169825936310607, -0.2392642548476636, -0.3445824527086725, -0.04679384247420697, -0.2528992036021554, -0.08260696393925036, -0.5712516571134669, -0.4470083254077771, -0.2932583741622123, -0.3387455342513581, -0.4866186030476229, -0.06331807761542517, -0.3572200832163284, -0.1150603039022681, 0.8852447089321018, 0.6316433502561769, 0.4442323857022434, -0.4354982715915861, -0.567134806996659, -0.03712121172034775, -0.4872541821309158, -0.04596503618660204, 0.7398007723265512, 0.6149817749924394, 0.3542761621387836, 0.4895181806153506, 0.6181825492132028, 0.1174651559860139, 0.4548917961099569, 0.138596628081939}; 25 | 26 | const PROGMEM float sv4[8 * VEC_DIM] = {-0.0983607, -0.847222, -0.89899, -0.414141, 0.391304, 0.111111, -0.931034, -0.833333, -0.390476, -0.196721, -0.875, -0.252525, 1, 0.582609, 0.155556, -0.982759, -0.733333, -0.047619, 0, -0.472222, -0.858586, 0.656566, 0.408696, -0.422222, -1, -0.6, -0.714286, -0.836066, -0.625, -0.272727, -0.131313, -0.00869565, -0.955556, 0, -0.2, -0.447619, -0.52459, -0.361111, -0.171717, -1, -1, -0.933333, -0.689655, -0.45, 0.0857143, -0.459016, -0.513889, -0.292929, -0.79798, -1, -0.777778, -0.448276, -0.233333, 0.0666667, -0.819672, -0.263889, -0.212121, 0.111111, -0.513043, -0.355556, -0.689655, 0.116667, -0.295238, -0.918033, -0.944444, -0.414141, -0.69697, -0.217391, -1, -0.534483, -0.516667, -0.561905}; 27 | 28 | const PROGMEM float yalpha5[7 * (NR_CLASS-1)] = {-0.08260696393925036, -0.2514909283334567, -0.3704326345542678, -0.3691091649891058, -0.2609971730793799, -0.305120280187051, -0.4167423330825637, -0.1150603039022681, -0.3551621174144381, -0.5216665302776792, -0.5513303355783986, -0.3612923799202565, -0.4267604336201976, -0.5892315361207794, -0.04596503618660204, -0.5834549771827471, -0.77770699261461, -0.74739587754181, -0.4718212422210239, -0.49409104193335, -0.6779610865489653, 0.138596628081939, 0.459624866262384, 0.7024049091483534, 0.6939734027006816, -0.5030685606396823, -0.5689412376525855, -0.781744048817286}; 29 | 30 | const PROGMEM float sv5[7 * VEC_DIM] = {-0.918033, -0.944444, -0.414141, -0.69697, -0.217391, -1, -0.534483, -0.516667, -0.561905, -1, -1, -0.79798, -0.454545, -0.321739, -0.622222, -0.62069, -0.383333, -0.447619, -0.459016, -0.222222, 0.252525, -0.313131, -0.2, -0.422222, -0.896552, -0.65, -1, -0.557377, -0.402778, 0.373737, -0.353535, 0.0608696, -0.444444, -0.551724, -0.5, 0.466667, 0.508197, -0.583333, -0.515152, -0.636364, 0.408696, -0.0888889, 0.793103, -0.5, -0.67619, 0.622951, 0.583333, -0.030303, -0.292929, -0.026087, 0.866667, 0.706897, -0.916667, -0.771429, 1, 0.291667, -0.0909091, -0.717172, 1, 1, 0.62069, -0.966667, -0.6}; 31 | 32 | const int scalePar[] = {-1,1}; 33 | const int low[] = {517,544,543,546,733,576,552,526,552}; 34 | const int high[] = {639,688,642,645,848,666,668,646,657}; 35 | int result[NR_CLASS]={0}; 36 | 37 | float const* const supportVectors[NR_CLASS] PROGMEM = { 38 | sv1, sv2, sv3, sv4, sv5, }; 39 | const float* const valuesForSupport[NR_CLASS] PROGMEM = { 40 | yalpha1, yalpha2, yalpha3, yalpha4, yalpha5, }; 41 | 42 | void scale(const int* sensor, float* scaledSensor){ 43 | for(int p=0; p 0) { 75 | result[i]++; 76 | } else { 77 | result[j]++; 78 | } 79 | rhoCounter++; 80 | } 81 | } 82 | 83 | 84 | int temp = 0; 85 | for(int t = 0; t < NR_CLASS; t++){ 86 | if(result[temp] <= result[t]){ 87 | recognizedClass = t; 88 | temp = t; 89 | } 90 | } 91 | 92 | 93 | Serial.println(recognizedClass, DEC); 94 | delay(500); 95 | for(int q = 0; q < NR_CLASS; q++){ 96 | result[q]=0; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Model_Examples/rbf/sketch_svm/svm_evaluate.ino: -------------------------------------------------------------------------------- 1 | #ifndef VEC_DIM 2 | #error 3 | #endif 4 | 5 | #include 6 | 7 | 8 | inline float svm_evaluate(int n_sv, float* coeffs, float* sv_class, float* sensors){ 9 | float result= 0; 10 | float* sv_current = sv_class; 11 | for (int i=0; i 2 | 3 | // In this section you should implement the handling of your sensor data, which you would like to classify. 4 | // and an example would be: 5 | int sensors[5] = {0}; 6 | 7 | // int sensor1, sensor2, sensor3, sensor4, sensor5; 8 | 9 | void setup(){ 10 | Serial.begin(115200); 11 | } 12 | 13 | void loop(){ 14 | 15 | //sensor1 = analogRead(0); 16 | //sensor2 = analogRead(1); 17 | //sensor3 = analogRead(2); 18 | //sensor4 = analogRead(3); 19 | //sensor5 = analogRead(4); 20 | //delay(600); 21 | // sensors= {sensor1, sensor2, sensor3, sensor4, sensor5}; 22 | 23 | svm_predict(sensors); 24 | } 25 | -------------------------------------------------------------------------------- /Model_Examples/sig/sketch_svm/sigmoid_kernel.ino: -------------------------------------------------------------------------------- 1 | #ifndef VEC_DIM 2 | #error 3 | #endif 4 | 5 | #ifndef GAMMA 6 | #error 7 | #endif 8 | 9 | #ifndef COEF0 10 | #error 11 | #endif 12 | 13 | #include 14 | 15 | 16 | inline float sigmoid_kernel(float* u, float* v){ 17 | float result=0; 18 | for (int j=0; j 2 | #define VEC_DIM 9 3 | 4 | #define SVM_TYPE c_svc 5 | #define KERNEL_TYPE sigmoid 6 | #define GAMMA 0.111111 7 | #define COEF0 0 8 | #define NR_CLASS 5 9 | #define TOTAL_SV 44 10 | const PROGMEM float rho[] = {0.660523, 0.247178, 0.19397, 0.256064, -0.0561636, 0.0215861, -0.0917099, 0.0323295, 0.0241942, -0.0793826}; 11 | const int label[] = {0, 1, 2, 3, 4}; 12 | const int nr_sv[] = {8, 9, 9, 8, 10}; 13 | const PROGMEM float yalpha1[8 * (NR_CLASS-1)] = {1, 1, 1, 0.5908915908032174, 1, 1, 1, 1, 1, 0.3801888895120982, 0, 0, 0, 0.3180633214857793, 1, 0, 1, 0, 0, 0, 0, 1, 0.3133207468729625, 0, 1, 0.9727535880815427, 0, 0, 0, 1, 0, 0}; 14 | 15 | const PROGMEM float sv1[8 * VEC_DIM] = {0.114754, 0.583333, 0.676768, 0.676768, 0.547826, 0.622222, 0.655172, 0.666667, 0.52381, 0.0983607, 0.791667, 0.79798, 0.717172, 0.6, 0.555556, 0.741379, 0.716667, 0.790476, 0.0983607, 0.861111, 0.959596, 0.818182, 0.617391, 0.488889, 0.689655, 0.65, 0.67619, 0.0819672, 0.805556, 1, 0.494949, 0.478261, 0.511111, 0.62069, 0.816667, 1, 0.147541, 0.902778, 0.919192, 0.515152, 0.617391, 0.511111, 0.603448, 0.766667, 0.92381, 0.0655738, 0.819444, 0.818182, 0.272727, 0.6, 0.6, 0.568966, 0.75, 0.942857, 0.0819672, 0.75, 0.919192, 0.59596, 0.513043, 0.555556, 0.517241, 0.766667, 0.885714, 0.213115, 0.847222, 0.919192, 0.616162, 0.46087, 0.711111, 0.431034, 0.85, 0.980952}; 16 | 17 | const PROGMEM float yalpha2[9 * (NR_CLASS-1)] = {1, -1, -1, -1, -1, -0.5908915908032173, -1, -0, -1, 0, 0, 0.4382504803351162, 1, 1, 1, 1, 1, 0.4014894348441783, 0, 0, 0.4395151718971399, 0.7714643387169527, 1, 1, 0, 0.1714104528089549, 0, 0, 0, 0.6513823177726588, 0, 0.6769957431113649, 1, 1, 1, 1}; 18 | 19 | const PROGMEM float sv2[9 * VEC_DIM] = {0.213115, 0.847222, 0.919192, 0.616162, 0.46087, 0.711111, 0.431034, 0.85, 0.980952, 0.42623, 0.0972222, 0.353535, 0.959596, 0.773913, 0.688889, 0.362069, -0.483333, 0.638095, 0.213115, 0.194444, 0.292929, 0.515152, 0.86087, 0.688889, 0.327586, 0.55, 0.333333, 0.0327869, -0.111111, 0.616162, 0.757576, 0.791304, 0.488889, 0.310345, -0.5, 0.561905, 0, -0.263889, 0.636364, 0.636364, 0.756522, 0.488889, 0.310345, -0.45, 0.580952, 0.131148, 0.0555556, 0.0707071, 0.353535, 0.86087, 0.377778, 0.327586, -0.45, 0.657143, 0.311475, 0.194444, 0.272727, 0.575758, 0.913043, 0.844444, 0.0862069, -0.4, 0.6, 0.180328, -0.166667, -0.0909091, 0.515152, 0.86087, 0.488889, 0.517241, -0.316667, 0.714286, 0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524}; 20 | 21 | const PROGMEM float yalpha3[9 * (NR_CLASS-1)] = {-1, -1, -1, -1, -0, -0, -0, -0.6982522109978776, -0, 0.4014894348441783, 0, -1, -1, -0, -0.8397399151792945, -1, -1, -0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0.3616923704127539, 0, 1}; 22 | 23 | const PROGMEM float sv3[9 * VEC_DIM] = {0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524, 0.180328, 0.138889, 0.757576, 0.818182, 0.791304, 0.488889, 0.362069, -0.45, 0.638095, 0.0327869, -0.555556, -0.292929, 0.555556, 0.617391, 0.466667, -0.551724, -0.216667, -0.180952, -0.0327869, -0.569444, 0.0707071, 0.272727, 0.478261, 0.355556, -0.603448, -0.35, -0.142857, -0.114754, -0.0277778, -0.79798, 0.373737, 0.513043, -0.266667, -0.517241, -0.883333, -0.828571, 0.147541, -0.541667, -0.717172, 0.313131, 0.46087, 0.111111, -0.482759, -0.583333, -0.638095, -0.229508, -0.916667, -0.676768, 0.212121, 0.530435, 0.444444, -0.637931, -0.583333, -0.0666667, -0.327869, -0.847222, -0.313131, 0.656566, 0.530435, 0.266667, -0.465517, -0.55, -0.0666667, -0.0983607, -0.847222, -0.89899, -0.414141, 0.391304, 0.111111, -0.931034, -0.833333, -0.390476}; 24 | 25 | const PROGMEM float yalpha4[8 * (NR_CLASS-1)] = {-0, -0, -0, -0, -0.3133207468729625, -0, -0, -1, -0, -1, -0, -0, -1, -0, -0, -1, 1, 0, 1, -1, -1, -0, -1, -1, 1, 0, 0, 1, 1, 0.7352540059550801, 0, 0}; 26 | 27 | const PROGMEM float sv4[8 * VEC_DIM] = {-0.0983607, -0.847222, -0.89899, -0.414141, 0.391304, 0.111111, -0.931034, -0.833333, -0.390476, -0.196721, -0.875, -0.252525, 1, 0.582609, 0.155556, -0.982759, -0.733333, -0.047619, 0, -0.472222, -0.858586, 0.656566, 0.408696, -0.422222, -1, -0.6, -0.714286, -0.885246, -0.638889, -0.474747, -0.353535, -0.252174, -0.933333, -0.137931, -0.45, -0.542857, -0.836066, -0.625, -0.272727, -0.131313, -0.00869565, -0.955556, 0, -0.2, -0.447619, -0.459016, -0.513889, -0.292929, -0.79798, -1, -0.777778, -0.448276, -0.233333, 0.0666667, -0.918033, -0.513889, -0.373737, -0.292929, -0.321739, -0.466667, -0.517241, 0.166667, -0.504762, -0.819672, -0.263889, -0.212121, 0.111111, -0.513043, -0.355556, -0.689655, 0.116667, -0.295238}; 28 | 29 | const PROGMEM float yalpha5[10 * (NR_CLASS-1)] = {-1, -0, -0, -1, -0, -0.4566853256751703, -0, -1, -0.5160682624063724, -0, -1, -0, -0.3823899634230476, -1, -0, -0, -1, -1, -1, -0, -1, -1, -1, -1, -1, -0, -0, -1, -0.3616923704127539, -0, 0, 0, 1, 1, -1, -0, -0, -0, -1, -1}; 30 | 31 | const PROGMEM float sv5[10 * VEC_DIM] = {-0.819672, -0.263889, -0.212121, 0.111111, -0.513043, -0.355556, -0.689655, 0.116667, -0.295238, -1, -1, -0.79798, -0.454545, -0.321739, -0.622222, -0.62069, -0.383333, -0.447619, -0.459016, -0.222222, 0.252525, -0.313131, -0.2, -0.422222, -0.896552, -0.65, -1, -0.557377, -0.402778, 0.373737, -0.353535, 0.0608696, -0.444444, -0.551724, -0.5, 0.466667, 0.508197, -0.583333, -0.515152, -0.636364, 0.408696, -0.0888889, 0.793103, -0.5, -0.67619, 0.622951, 0.583333, -0.030303, -0.292929, -0.026087, 0.866667, 0.706897, -0.916667, -0.771429, 1, 0.291667, -0.0909091, -0.717172, 1, 1, 0.62069, -0.966667, -0.6, 0.57377, 0.319444, -0.252525, -0.515152, 0.373913, 0.422222, 0.603448, -0.666667, -0.447619, 0.278689, 0.180556, 0.030303, -0.373737, 0.356522, -0.577778, 0.862069, -0.7, -0.619048, 0.459016, -0.0972222, -0.232323, -0.757576, -0.113043, 0.0666667, 0.965517, -0.416667, -0.352381}; 32 | 33 | const int scalePar[] = {-1,1}; 34 | const int low[] = {517,544,543,546,733,576,552,526,552}; 35 | const int high[] = {639,688,642,645,848,666,668,646,657}; 36 | int result[NR_CLASS]={0}; 37 | 38 | float const* const supportVectors[NR_CLASS] PROGMEM = { 39 | sv1, sv2, sv3, sv4, sv5, }; 40 | const float* const valuesForSupport[NR_CLASS] PROGMEM = { 41 | yalpha1, yalpha2, yalpha3, yalpha4, yalpha5, }; 42 | 43 | void scale(const int* sensor, float* scaledSensor){ 44 | for(int p=0; p 0) { 76 | result[i]++; 77 | } else { 78 | result[j]++; 79 | } 80 | rhoCounter++; 81 | } 82 | } 83 | 84 | 85 | int temp = 0; 86 | for(int t = 0; t < NR_CLASS; t++){ 87 | if(result[temp] <= result[t]){ 88 | recognizedClass = t; 89 | temp = t; 90 | } 91 | } 92 | 93 | 94 | Serial.println(recognizedClass, DEC); 95 | delay(500); 96 | for(int q = 0; q < NR_CLASS; q++){ 97 | result[q]=0; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Model_Examples/sig/sketch_svm/svm_evaluate.ino: -------------------------------------------------------------------------------- 1 | #ifndef VEC_DIM 2 | #error 3 | #endif 4 | 5 | #include 6 | 7 | 8 | inline float svm_evaluate(int n_sv, float* coeffs, float* sv_class, float* sensors){ 9 | float result= 0; 10 | float* sv_current = sv_class; 11 | for (int i=0; i). 11 | - Use Arduino-SVM to create an Arduino sketch with which a prediction is made to which of the trained classes newly measured data could belong. To do this you have to start the processing sketch Arduino-SVM and insert in the textfields the paths to the LibSVM model, and the LibSVM scaling data file (in the example the file is Model_Examples/range). You have to insert the path in which the newly created folder for the Arduino sketch should be saved. To use the build Arduino sketch you have to insert in measurement.ino your code to measure your sensor data, the data must be in the same order as the training data and all done preprocessing steps which have been used before the training data was scaled and used for training with help of LibSVM must be done with newly measured data as well. Your data should be saved then in an int array and forwarded to the prediction function. 12 | - In rbf_example you can see a complete (and commented) Arduino sketch in which the data of 9 sensors is classified to 5 classes using an rbf kernel. 13 | - The build Arduino sketch forwards the recognized class (label: 0,1...n) to the Serial Monitor with a baud rate of 115200. 14 | 15 | Status 16 | ========= 17 | This is beta code. We've done ad-hoc testing primarily with a RBF kernel. Please let us know if you find mistakes and feel free to change the code to your needs. To use the program you have to have LibSVM, Arduino and Processing installed on your computer, also you nead the ControleP5 libery for processing. We tested with LibSVM 3.12, Arduino 1.0.6 and Processing 2.2.1. 18 | -------------------------------------------------------------------------------- /rbf_example/sketch_svm/measurement.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // here the data is measured which should be predicted by the SVM 4 | int sensor1, sensor2, sensor3, sensor4, sensor5; 5 | int sensor6, sensor7, sensor8, sensor9; 6 | 7 | void setup(){ 8 | Serial.begin(115200); 9 | 10 | pinMode(8,OUTPUT); 11 | pinMode(9,OUTPUT); 12 | 13 | } 14 | 15 | void loop(){ 16 | 17 | 18 | digitalWrite(8,LOW); 19 | digitalWrite(9,HIGH); 20 | 21 | 22 | 23 | 24 | sensor1 = analogRead(0); 25 | sensor2 = analogRead(1); 26 | sensor3 = analogRead(2); 27 | sensor4 = analogRead(3); 28 | sensor5 = analogRead(4); 29 | 30 | delay(200); 31 | digitalWrite(8,HIGH); 32 | digitalWrite(9,LOW); 33 | 34 | 35 | delay(200); 36 | 37 | sensor6 = analogRead(0); 38 | sensor7 = analogRead(1); 39 | sensor8 = analogRead(2); 40 | sensor9 = analogRead(3); 41 | 42 | delay(200); 43 | 44 | 45 | digitalWrite(8,LOW); 46 | digitalWrite(9,HIGH); 47 | 48 | int sensors[9]= {sensor1, sensor2, sensor3, sensor4, sensor5, sensor6, sensor7, sensor8, sensor9}; 49 | // prediction funktion is called with the mesurd data 50 | svm_predict(sensors); 51 | } 52 | -------------------------------------------------------------------------------- /rbf_example/sketch_svm/rbf_kernel.ino: -------------------------------------------------------------------------------- 1 | #ifndef VEC_DIM 2 | #error "must define the dimension of vectors." 3 | #endif 4 | 5 | #ifndef GAMMA 6 | #error "must define gamma for rbf kernel." 7 | #endif 8 | 9 | #include 10 | /* 11 | * \param u a vector in program memory 12 | * \param v a vector in main memory 13 | * 14 | * \pre the CPP-constant VEC_DIM defines the dimension of support vectors and sensors. 15 | */ 16 | inline float rbf_kernel(float* u, float* v){ 17 | float result=0; 18 | // calculate squared norm 19 | for (int j=0; j 2 | 3 | #define VEC_DIM 9 // Dimension of the measured feature vectors (number of values which belong to one measurement) 4 | #define SVM_TYPE c_svc // SVM Type from the LibSVM model 5 | #define KERNEL_TYPE rbf // Kernel type from the LibSVM model 6 | #define GAMMA 1 // Gamma value from the LibSVM model 7 | #define NR_CLASS 5 // Number of classes which are distinguished 8 | #define TOTAL_SV 34 // Number of support vectors 9 | const PROGMEM float rho[] = {0.36276, 0.371906, 0.473969, 0.451522, 0.137938, 0.25699, 0.231955, 0.142067, 0.0977635, -0.0295956};// rho values from the LibSVM model 10 | const int label[] = {0, 1, 2, 3, 4};// Labels from the LibSVM moddel 11 | const int nr_sv[] = {5, 6, 8, 8, 7}; // Number of support vectors for each class 12 | 13 | // suppport vectors and alpha values for each class: the support vectors and alpha values are saved in order directly after one another. 14 | const PROGMEM float yalpha1[5 * (NR_CLASS-1)] = {2.107335316049639, 0, 0.2964265104934171, 0.2295626192109151, 0.05271834980593445, 0.732576868565294, 0.1003888070674556, 0, 0.5958535967753404, 0.3937788597496962, 0.7819447269800799, 0.1095371855556466, 0, 0.6412513842416325, 0.4244461486714203, 0.7736147721476789, 0.1085783037267564, 0, 0.629383488716891, 0.4167085121221615}; 15 | 16 | const PROGMEM float sv1[5 * VEC_DIM] = {0.114754, 0.583333, 0.676768, 0.676768, 0.547826, 0.622222, 0.655172, 0.666667, 0.52381, 0.0983607, 0.861111, 0.959596, 0.818182, 0.617391, 0.488889, 0.689655, 0.65, 0.67619, 0.0655738, 0.819444, 0.818182, 0.272727, 0.6, 0.6, 0.568966, 0.75, 0.942857, -0.0819672, 1, 0.959596, 0.434343, 0.513043, 0.533333, 0.534483, 0.766667, 1, 0.196721, 0.694444, 1, 0.555556, 0.46087, 0.533333, 0.551724, 1, 1}; 17 | 18 | const PROGMEM float yalpha2[6 * (NR_CLASS-1)] = {0.05271834980593445, -0, -1.736859881676639, -0, -0, -0.3689736056802617, 0.3937788597496962, 0.2591110144046342, 0.8367291914326392, 0.6725956776744122, 0.03482470347779317, 0.7436913873588609, 0.4244461486714203, 0.2646118216882179, 0.8944199942693069, 0.581171811381979, 0.01491533353693937, 0.8116112072253026, 0.4167085121221615, 0.260659683970744, 0.8813026753556298, 0.542198226750192, 0.03873916724600095, 0.8058610806097716}; 19 | 20 | const PROGMEM float sv2[6 * VEC_DIM] = {0.196721, 0.694444, 1, 0.555556, 0.46087, 0.533333, 0.551724, 1, 1, 0.47541, 0.0416667, 0.212121, 0.838384, 0.878261, 0.844444, 0.327586, -0.533333, 0.657143, 0.213115, 0.194444, 0.292929, 0.515152, 0.86087, 0.688889, 0.327586, 0.55, 0.333333, 0, -0.263889, 0.636364, 0.636364, 0.756522, 0.488889, 0.310345, -0.45, 0.580952, 0.180328, -0.166667, -0.0909091, 0.515152, 0.86087, 0.488889, 0.517241, -0.316667, 0.714286, 0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524}; 21 | 22 | const PROGMEM float yalpha3[8 * (NR_CLASS-1)] = {-0.3689736056802617, -0.580209308203005, -0.1093331482812802, -0.2916458132181204, -0.3582523908090453, -0.07469041930962894, -0, -0.4159890905458756, 0.7436913873588609, 0.09481529177328665, -0.2795322611114798, -0.5077933408456813, -0.4876216582817534, -0.05530164919925538, -0, -0.5712516571134669, 0.8116112072253026, 0.2223914172017729, 0, 0.8614699454524755, 0.7287595824479804, 0.114259993040315, 0.01592139013398465, 0.8852447089321018, 0.8058610806097716, 0.2295852587515451, 0.1677228201223715, 0.5573917025217557, 0.6785914797644198, 0.1349397367869411, 0, 0.7398007723265512}; 23 | 24 | const PROGMEM float sv3[8 * VEC_DIM] = {0.262295, 0.472222, -0.232323, 0.414141, 0.86087, 0.444444, 0.293103, -0.566667, 0.809524, 0.180328, 0.138889, 0.757576, 0.818182, 0.791304, 0.488889, 0.362069, -0.45, 0.638095, 0.0327869, -0.555556, -0.292929, 0.555556, 0.617391, 0.466667, -0.551724, -0.216667, -0.180952, -0.0327869, -0.569444, 0.0707071, 0.272727, 0.478261, 0.355556, -0.603448, -0.35, -0.142857, -0.114754, -0.0277778, -0.79798, 0.373737, 0.513043, -0.266667, -0.517241, -0.883333, -0.828571, -0.0163934, -0.930556, -1, 0.292929, 0.443478, 0.2, -0.775862, -0.566667, -0.104762, -0.327869, -0.847222, -0.313131, 0.656566, 0.530435, 0.266667, -0.465517, -0.55, -0.0666667, -0.0983607, -0.847222, -0.89899, -0.414141, 0.391304, 0.111111, -0.931034, -0.833333, -0.390476}; 25 | 26 | const PROGMEM float yalpha4[8 * (NR_CLASS-1)] = {-0.4159890905458756, -0.3557046763627751, -0.2169825936310607, -0.2392642548476636, -0.3445824527086725, -0.04679384247420697, -0.2528992036021554, -0.08260696393925036, -0.5712516571134669, -0.4470083254077771, -0.2932583741622123, -0.3387455342513581, -0.4866186030476229, -0.06331807761542517, -0.3572200832163284, -0.1150603039022681, 0.8852447089321018, 0.6316433502561769, 0.4442323857022434, -0.4354982715915861, -0.567134806996659, -0.03712121172034775, -0.4872541821309158, -0.04596503618660204, 0.7398007723265512, 0.6149817749924394, 0.3542761621387836, 0.4895181806153506, 0.6181825492132028, 0.1174651559860139, 0.4548917961099569, 0.138596628081939}; 27 | 28 | const PROGMEM float sv4[8 * VEC_DIM] = {-0.0983607, -0.847222, -0.89899, -0.414141, 0.391304, 0.111111, -0.931034, -0.833333, -0.390476, -0.196721, -0.875, -0.252525, 1, 0.582609, 0.155556, -0.982759, -0.733333, -0.047619, 0, -0.472222, -0.858586, 0.656566, 0.408696, -0.422222, -1, -0.6, -0.714286, -0.836066, -0.625, -0.272727, -0.131313, -0.00869565, -0.955556, 0, -0.2, -0.447619, -0.52459, -0.361111, -0.171717, -1, -1, -0.933333, -0.689655, -0.45, 0.0857143, -0.459016, -0.513889, -0.292929, -0.79798, -1, -0.777778, -0.448276, -0.233333, 0.0666667, -0.819672, -0.263889, -0.212121, 0.111111, -0.513043, -0.355556, -0.689655, 0.116667, -0.295238, -0.918033, -0.944444, -0.414141, -0.69697, -0.217391, -1, -0.534483, -0.516667, -0.561905}; 29 | 30 | const PROGMEM float yalpha5[7 * (NR_CLASS-1)] = {-0.08260696393925036, -0.2514909283334567, -0.3704326345542678, -0.3691091649891058, -0.2609971730793799, -0.305120280187051, -0.4167423330825637, -0.1150603039022681, -0.3551621174144381, -0.5216665302776792, -0.5513303355783986, -0.3612923799202565, -0.4267604336201976, -0.5892315361207794, -0.04596503618660204, -0.5834549771827471, -0.77770699261461, -0.74739587754181, -0.4718212422210239, -0.49409104193335, -0.6779610865489653, 0.138596628081939, 0.459624866262384, 0.7024049091483534, 0.6939734027006816, -0.5030685606396823, -0.5689412376525855, -0.781744048817286}; 31 | 32 | const PROGMEM float sv5[7 * VEC_DIM] = {-0.918033, -0.944444, -0.414141, -0.69697, -0.217391, -1, -0.534483, -0.516667, -0.561905, -1, -1, -0.79798, -0.454545, -0.321739, -0.622222, -0.62069, -0.383333, -0.447619, -0.459016, -0.222222, 0.252525, -0.313131, -0.2, -0.422222, -0.896552, -0.65, -1, -0.557377, -0.402778, 0.373737, -0.353535, 0.0608696, -0.444444, -0.551724, -0.5, 0.466667, 0.508197, -0.583333, -0.515152, -0.636364, 0.408696, -0.0888889, 0.793103, -0.5, -0.67619, 0.622951, 0.583333, -0.030303, -0.292929, -0.026087, 0.866667, 0.706897, -0.916667, -0.771429, 1, 0.291667, -0.0909091, -0.717172, 1, 1, 0.62069, -0.966667, -0.6}; 33 | 34 | // the scaling parameters from the scaling file of LibSVM 35 | const int scalePar[] = {-1,1}; 36 | const int low[] = {517,544,543,546,733,576,552,526,552}; 37 | const int high[] = {639,688,642,645,848,666,668,646,657}; 38 | // in this array the votes for the different classes are saved 39 | int result[NR_CLASS]={0}; 40 | 41 | // all support vectors and alpha values 42 | float const* const supportVectors[NR_CLASS] PROGMEM = { 43 | sv1, sv2, sv3, sv4, sv5, }; 44 | const float* const valuesForSupport[NR_CLASS] PROGMEM = { 45 | yalpha1, yalpha2, yalpha3, yalpha4, yalpha5, }; 46 | 47 | // scaling function: in this function the new sensor data which are measured are scaled with help of the data from the scaling file. 48 | void scale(const int* sensor, float* scaledSensor){ 49 | for(int p=0; p 0) { 81 | result[i]++; 82 | } else { 83 | result[j]++; 84 | } 85 | rhoCounter++; 86 | } 87 | } 88 | 89 | // find out which class has the most votes 90 | int temp = 0; 91 | for(int t = 0; t < NR_CLASS; t++){ 92 | if(result[temp] <= result[t]){ 93 | recognizedClass = t; 94 | temp = t; 95 | } 96 | } 97 | 98 | // outpot of the predicted class. 99 | Serial.println(recognizedClass, DEC); 100 | delay(500); 101 | for(int q = 0; q < NR_CLASS; q++){ 102 | result[q]=0; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /rbf_example/sketch_svm/svm_evaluate.ino: -------------------------------------------------------------------------------- 1 | #ifndef VEC_DIM 2 | #error "must define the dimension of vectors." 3 | #endif 4 | 5 | #include 6 | 7 | /* 8 | * Evaluates whether the given measurements in `sensors` belongs to the given class. 9 | * Computes: 10 | * 11 | * \sum_{i=0}^{n_sv} (coeffs_{i} K(x_i, x)) - \rho 12 | * 13 | * \param n_sv the number of support vectors for this class 14 | * \param coeffs an array of `n_sv` coefficients in program memory. 15 | * \param sv_class an program memory `n_sv` x `VEC_DIM`-array of the support vectors' coordinates in column-major order, i.e. the coordinates of a SV are consecutive values in the array. 16 | * \param rho a scalar offset 17 | * \param sensors an VEC_DIM array in main memory of the sensor measurements to be evaluated. 18 | * 19 | * \pre the CPP-constant VEC_DIM defines the dimension of support vectors and sensors. 20 | */ 21 | 22 | inline float svm_evaluate(int n_sv, float* coeffs, float* sv_class, float* sensors){ 23 | float result= 0; 24 | float* sv_current = sv_class; 25 | for (int i=0; i