windows/svm-toy.cpp
Go to the documentation of this file.
1 #include <windows.h>
2 #include <windowsx.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <list>
7 #include "../../svm.h"
8 using namespace std;
9 
10 #define DEFAULT_PARAM "-t 2 -c 100"
11 #define XLEN 500
12 #define YLEN 500
13 #define DrawLine(dc,x1,y1,x2,y2,c) \
14  do { \
15  HPEN hpen = CreatePen(PS_SOLID,0,c); \
16  HPEN horig = SelectPen(dc,hpen); \
17  MoveToEx(dc,x1,y1,NULL); \
18  LineTo(dc,x2,y2); \
19  SelectPen(dc,horig); \
20  DeletePen(hpen); \
21  } while(0)
22 
23 using namespace std;
24 
25 COLORREF colors[] =
26 {
27  RGB(0, 0, 0),
28  RGB(0, 120, 120),
29  RGB(120, 120, 0),
30  RGB(120, 0, 120),
31  RGB(0, 200, 200),
32  RGB(200, 200, 0),
33  RGB(200, 0, 200)
34 };
35 
37 HBITMAP buffer;
40 HBRUSH brush1, brush2, brush3;
41 HWND edit;
42 
43 enum
44 {
47 };
48 
49 struct point
50 {
51  double x, y;
52  signed char value;
53 };
54 
55 list<point> point_list;
56 int current_value = 1;
57 
58 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
59 
60 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
61  PSTR szCmdLine, int iCmdShow)
62 {
63  static char szAppName[] = "SvmToy";
64  MSG msg;
65  WNDCLASSEX wndclass;
66 
67  wndclass.cbSize = sizeof(wndclass);
68  wndclass.style = CS_HREDRAW | CS_VREDRAW;
69  wndclass.lpfnWndProc = WndProc;
70  wndclass.cbClsExtra = 0;
71  wndclass.cbWndExtra = 0;
72  wndclass.hInstance = hInstance;
73  wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
74  wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
75  wndclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
76  wndclass.lpszMenuName = NULL;
77  wndclass.lpszClassName = szAppName;
78  wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
79 
80  RegisterClassEx(&wndclass);
81 
82  main_window = CreateWindow(szAppName, // window class name
83  "SVM Toy", // window caption
84  WS_OVERLAPPEDWINDOW,// window style
85  CW_USEDEFAULT, // initial x position
86  CW_USEDEFAULT, // initial y position
87  XLEN, // initial x size
88  YLEN + 52, // initial y size
89  NULL, // parent window handle
90  NULL, // window menu handle
91  hInstance, // program instance handle
92  NULL); // creation parameters
93 
94  ShowWindow(main_window, iCmdShow);
95  UpdateWindow(main_window);
96 
97  CreateWindow("button", "Change", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
98  0, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_CHANGE, hInstance, NULL);
99  CreateWindow("button", "Run", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
100  50, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_RUN, hInstance, NULL);
101  CreateWindow("button", "Clear", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
102  100, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_CLEAR, hInstance, NULL);
103  CreateWindow("button", "Save", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
104  150, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_SAVE, hInstance, NULL);
105  CreateWindow("button", "Load", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
106  200, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_LOAD, hInstance, NULL);
107 
108  edit = CreateWindow("edit", NULL, WS_CHILD | WS_VISIBLE,
109  250, YLEN, 250, 25, main_window, (HMENU) ID_EDIT, hInstance, NULL);
110 
111  Edit_SetText(edit, DEFAULT_PARAM);
112 
113  brush1 = CreateSolidBrush(colors[4]);
114  brush2 = CreateSolidBrush(colors[5]);
115  brush3 = CreateSolidBrush(colors[6]);
116 
117  window_dc = GetDC(main_window);
118  buffer = CreateCompatibleBitmap(window_dc, XLEN, YLEN);
119  buffer_dc = CreateCompatibleDC(window_dc);
120  SelectObject(buffer_dc, buffer);
121  PatBlt(buffer_dc, 0, 0, XLEN, YLEN, BLACKNESS);
122 
123  while (GetMessage(&msg, NULL, 0, 0))
124  {
125  TranslateMessage(&msg);
126  DispatchMessage(&msg);
127  }
128  return msg.wParam;
129 }
130 
131 int getfilename(HWND hWnd, char *filename, int len, int save)
132 {
133  OPENFILENAME OpenFileName;
134  memset(&OpenFileName, 0, sizeof(OpenFileName));
135  filename[0] = '\0';
136 
137  OpenFileName.lStructSize = sizeof(OPENFILENAME);
138  OpenFileName.hwndOwner = hWnd;
139  OpenFileName.lpstrFile = filename;
140  OpenFileName.nMaxFile = len;
141  OpenFileName.Flags = 0;
142 
143  return save ? GetSaveFileName(&OpenFileName) : GetOpenFileName(&OpenFileName);
144 }
145 
146 void clear_all()
147 {
148  point_list.clear();
149  PatBlt(buffer_dc, 0, 0, XLEN, YLEN, BLACKNESS);
150  InvalidateRect(main_window, 0, 0);
151 }
152 
153 HBRUSH choose_brush(int v)
154 {
155  if (v == 1) return brush1;
156  else if (v == 2) return brush2;
157  else return brush3;
158 }
159 
160 void draw_point(const point & p)
161 {
162  RECT rect;
163  rect.left = int(p.x * XLEN);
164  rect.top = int(p.y * YLEN);
165  rect.right = int(p.x * XLEN) + 3;
166  rect.bottom = int(p.y * YLEN) + 3;
167  FillRect(window_dc, &rect, choose_brush(p.value));
168  FillRect(buffer_dc, &rect, choose_brush(p.value));
169 }
170 
172 {
173  for (list<point>::iterator p = point_list.begin(); p != point_list.end(); p++)
174  draw_point(*p);
175 }
176 
178 {
179  // guard
180  if (point_list.empty()) return;
181 
183  int i, j;
184 
185  // default values
186  param.svm_type = C_SVC;
187  param.kernel_type = RBF;
188  param.degree = 3;
189  param.gamma = 0;
190  param.coef0 = 0;
191  param.nu = 0.5;
192  param.cache_size = 100;
193  param.C = 1;
194  param.eps = 1e-3;
195  param.p = 0.1;
196  param.shrinking = 1;
197  param.probability = 0;
198  param.nr_weight = 0;
199  param.weight_label = NULL;
200  param.weight = NULL;
201 
202  // parse options
203  char str[1024];
204  Edit_GetLine(edit, 0, str, sizeof(str));
205  const char *p = str;
206 
207  while (1)
208  {
209  while (*p && *p != '-')
210  p++;
211 
212  if (*p == '\0')
213  break;
214 
215  p++;
216  switch (*p++)
217  {
218  case 's':
219  param.svm_type = atoi(p);
220  break;
221  case 't':
222  param.kernel_type = atoi(p);
223  break;
224  case 'd':
225  param.degree = atoi(p);
226  break;
227  case 'g':
228  param.gamma = atof(p);
229  break;
230  case 'r':
231  param.coef0 = atof(p);
232  break;
233  case 'n':
234  param.nu = atof(p);
235  break;
236  case 'm':
237  param.cache_size = atof(p);
238  break;
239  case 'c':
240  param.C = atof(p);
241  break;
242  case 'e':
243  param.eps = atof(p);
244  break;
245  case 'p':
246  param.p = atof(p);
247  break;
248  case 'h':
249  param.shrinking = atoi(p);
250  break;
251  case 'b':
252  param.probability = atoi(p);
253  break;
254  case 'w':
255  ++param.nr_weight;
256  param.weight_label = (int *)realloc(param.weight_label, sizeof(int) * param.nr_weight);
257  param.weight = (double *)realloc(param.weight, sizeof(double) * param.nr_weight);
258  param.weight_label[param.nr_weight - 1] = atoi(p);
259  while (*p && !isspace(*p)) ++p;
260  param.weight[param.nr_weight - 1] = atof(p);
261  break;
262  }
263  }
264 
265  // build problem
267 
268  prob.l = point_list.size();
269  prob.y = new double[prob.l];
270 
271  if (param.kernel_type == PRECOMPUTED)
272  {
273  }
274  else if (param.svm_type == EPSILON_SVR ||
275  param.svm_type == NU_SVR)
276  {
277  if (param.gamma == 0) param.gamma = 1;
278  svm_node *x_space = new svm_node[2 * prob.l];
279  prob.x = new svm_node *[prob.l];
280 
281  i = 0;
282  for (list<point>::iterator q = point_list.begin(); q != point_list.end(); q++, i++)
283  {
284  x_space[2 * i].index = 1;
285  x_space[2 * i].value = q->x;
286  x_space[2 * i + 1].index = -1;
287  prob.x[i] = &x_space[2 * i];
288  prob.y[i] = q->y;
289  }
290 
291  // build model & classify
292  svm_model *model = svm_train(&prob, &param);
293  svm_node x[2];
294  x[0].index = 1;
295  x[1].index = -1;
296  int *j = new int[XLEN];
297 
298  for (i = 0; i < XLEN; i++)
299  {
300  x[0].value = (double) i / XLEN;
301  j[i] = (int)(YLEN * svm_predict(model, x));
302  }
303 
304  DrawLine(buffer_dc, 0, 0, 0, YLEN, colors[0]);
305  DrawLine(window_dc, 0, 0, 0, YLEN, colors[0]);
306 
307  int p = (int)(param.p * YLEN);
308  for (int i = 1; i < XLEN; i++)
309  {
310  DrawLine(buffer_dc, i, 0, i, YLEN, colors[0]);
311  DrawLine(window_dc, i, 0, i, YLEN, colors[0]);
312 
313  DrawLine(buffer_dc, i - 1, j[i - 1], i, j[i], colors[5]);
314  DrawLine(window_dc, i - 1, j[i - 1], i, j[i], colors[5]);
315 
316  if (param.svm_type == EPSILON_SVR)
317  {
318  DrawLine(buffer_dc, i - 1, j[i - 1] + p, i, j[i] + p, colors[2]);
319  DrawLine(window_dc, i - 1, j[i - 1] + p, i, j[i] + p, colors[2]);
320 
321  DrawLine(buffer_dc, i - 1, j[i - 1] - p, i, j[i] - p, colors[2]);
322  DrawLine(window_dc, i - 1, j[i - 1] - p, i, j[i] - p, colors[2]);
323  }
324  }
325 
327  delete[] j;
328  delete[] x_space;
329  delete[] prob.x;
330  delete[] prob.y;
331  }
332  else
333  {
334  if (param.gamma == 0) param.gamma = 0.5;
335  svm_node *x_space = new svm_node[3 * prob.l];
336  prob.x = new svm_node *[prob.l];
337 
338  i = 0;
339  for (list<point>::iterator q = point_list.begin(); q != point_list.end(); q++, i++)
340  {
341  x_space[3 * i].index = 1;
342  x_space[3 * i].value = q->x;
343  x_space[3 * i + 1].index = 2;
344  x_space[3 * i + 1].value = q->y;
345  x_space[3 * i + 2].index = -1;
346  prob.x[i] = &x_space[3 * i];
347  prob.y[i] = q->value;
348  }
349 
350  // build model & classify
351  svm_model *model = svm_train(&prob, &param);
352  svm_node x[3];
353  x[0].index = 1;
354  x[1].index = 2;
355  x[2].index = -1;
356 
357  for (i = 0; i < XLEN; i++)
358  for (j = 0; j < YLEN; j++)
359  {
360  x[0].value = (double) i / XLEN;
361  x[1].value = (double) j / YLEN;
362  double d = svm_predict(model, x);
363  if (param.svm_type == ONE_CLASS && d < 0) d = 2;
364  SetPixel(window_dc, i, j, colors[(int)d]);
365  SetPixel(buffer_dc, i, j, colors[(int)d]);
366  }
367 
369  delete[] x_space;
370  delete[] prob.x;
371  delete[] prob.y;
372  }
373  free(param.weight_label);
374  free(param.weight);
375  draw_all_points();
376 }
377 
378 LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
379 {
380  HDC hdc;
381  PAINTSTRUCT ps;
382 
383  switch (iMsg)
384  {
385  case WM_LBUTTONDOWN:
386  {
387  int x = LOWORD(lParam);
388  int y = HIWORD(lParam);
389  point p = {(double)x / XLEN, (double)y / YLEN, current_value};
390  point_list.push_back(p);
391  draw_point(p);
392  }
393  return 0;
394  case WM_PAINT:
395  {
396  hdc = BeginPaint(hwnd, &ps);
397  BitBlt(hdc, 0, 0, XLEN, YLEN, buffer_dc, 0, 0, SRCCOPY);
398  EndPaint(hwnd, &ps);
399  }
400  return 0;
401  case WM_COMMAND:
402  {
403  int id = LOWORD(wParam);
404  switch (id)
405  {
406  case ID_BUTTON_CHANGE:
407  ++current_value;
408  if (current_value > 3) current_value = 1;
409  break;
410  case ID_BUTTON_RUN:
412  break;
413  case ID_BUTTON_CLEAR:
414  clear_all();
415  break;
416  case ID_BUTTON_SAVE:
417  {
418  char filename[1024];
419  if (getfilename(hwnd, filename, 1024, 1))
420  {
421  FILE *fp = fopen(filename, "w");
422 
423  char str[1024];
424  Edit_GetLine(edit, 0, str, sizeof(str));
425  const char *p = str;
426  const char* svm_type_str = strstr(p, "-s ");
427  int svm_type = C_SVC;
428  if (svm_type_str != NULL)
429  sscanf(svm_type_str, "-s %d", &svm_type);
430 
431  if (fp)
432  {
433  if (svm_type == EPSILON_SVR || svm_type == NU_SVR)
434  {
435  for (list<point>::iterator p = point_list.begin(); p != point_list.end(); p++)
436  fprintf(fp, "%f 1:%f\n", p->y, p->x);
437  }
438  else
439  {
440  for (list<point>::iterator p = point_list.begin(); p != point_list.end(); p++)
441  fprintf(fp, "%d 1:%f 2:%f\n", p->value, p->x, p->y);
442  }
443  fclose(fp);
444  }
445  }
446  }
447  break;
448  case ID_BUTTON_LOAD:
449  {
450  char filename[1024];
451  if (getfilename(hwnd, filename, 1024, 0))
452  {
453  FILE *fp = fopen(filename, "r");
454  if (fp)
455  {
456  clear_all();
457  char buf[4096];
458  while (fgets(buf, sizeof(buf), fp))
459  {
460  int v;
461  double x, y;
462  if (sscanf(buf, "%d%*d:%lf%*d:%lf", &v, &x, &y) == 3)
463  {
464  point p = {x, y, v};
465  point_list.push_back(p);
466  }
467  else if (sscanf(buf, "%lf%*d:%lf", &y, &x) == 2)
468  {
469  point p = {x, y, current_value};
470  point_list.push_back(p);
471  }
472  else
473  break;
474  }
475  fclose(fp);
476  draw_all_points();
477  }
478  }
479  }
480  break;
481  }
482  }
483  return 0;
484  case WM_DESTROY:
485  PostQuitMessage(0);
486  return 0;
487  }
488 
489  return DefWindowProc(hwnd, iMsg, wParam, lParam);
490 }
d
HBRUSH brush3
struct svm_problem prob
Definition: svmtrain.c:60
void button_run_clicked()
struct svm_parameter param
Definition: svmtrain.c:59
def svm_train(arg1, arg2=None, arg3=None)
Definition: svmutil.py:77
HBRUSH brush1
HBITMAP buffer
Definition: svm.h:25
double value
Definition: svm.h:15
#define DEFAULT_PARAM
int nr_weight
Definition: svm.h:40
int * weight_label
Definition: svm.h:41
int getfilename(HWND hWnd, char *filename, int len, int save)
void draw_point(const point &p)
Definition: svm.h:25
#define XLEN
HDC window_dc
HBRUSH brush2
HWND edit
Definition: svm.h:52
double p
Definition: svm.h:44
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM)
def svm_predict(y, x, m, options="")
Definition: svmutil.py:164
struct svm_node * x
Definition: svm-predict.c:12
void draw_all_points()
double cache_size
Definition: svm.h:37
double y
Definition: callbacks.cpp:36
void clear_all()
double eps
Definition: svm.h:38
int shrinking
Definition: svm.h:45
HDC buffer_dc
struct svm_node ** x
Definition: svm.h:22
void svm_free_and_destroy_model(svm_model **model_ptr_ptr)
Definition: svm.cpp:3013
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
int current_value
double x
Definition: callbacks.cpp:36
Definition: svm.h:26
HWND main_window
int index
Definition: svm.h:14
#define DrawLine(dc, x1, y1, x2, y2, c)
COLORREF colors[]
signed char value
Definition: callbacks.cpp:37
int probability
Definition: svm.h:46
int degree
Definition: svm.h:32
Definition: svm.h:25
Definition: svm.h:12
HBRUSH choose_brush(int v)
double * y
Definition: svm.h:21
double gamma
Definition: svm.h:33
#define YLEN
int l
Definition: svm.h:20
double * weight
Definition: svm.h:42
double C
Definition: svm.h:39
int svm_type
Definition: svm.h:30
double nu
Definition: svm.h:43
struct svm_model * model
Definition: svmtrain.c:61
double coef0
Definition: svm.h:34
int kernel_type
Definition: svm.h:31
struct svm_node * x_space
Definition: svmtrain.c:62
list< point > point_list


ml_classifiers
Author(s): Scott Niekum , Joshua Whitley
autogenerated on Sun Dec 15 2019 03:53:50