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