eluka 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/.document +5 -0
  2. data/DOCUMENTATION_STANDARDS +39 -0
  3. data/Gemfile +13 -0
  4. data/Gemfile.lock +20 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +19 -0
  7. data/Rakefile +69 -0
  8. data/VERSION +1 -0
  9. data/examples/example.rb +59 -0
  10. data/ext/libsvm/COPYRIGHT +31 -0
  11. data/ext/libsvm/FAQ.html +1749 -0
  12. data/ext/libsvm/Makefile +25 -0
  13. data/ext/libsvm/Makefile.win +33 -0
  14. data/ext/libsvm/README +733 -0
  15. data/ext/libsvm/extconf.rb +1 -0
  16. data/ext/libsvm/heart_scale +270 -0
  17. data/ext/libsvm/java/Makefile +25 -0
  18. data/ext/libsvm/java/libsvm.jar +0 -0
  19. data/ext/libsvm/java/libsvm/svm.java +2776 -0
  20. data/ext/libsvm/java/libsvm/svm.m4 +2776 -0
  21. data/ext/libsvm/java/libsvm/svm_model.java +21 -0
  22. data/ext/libsvm/java/libsvm/svm_node.java +6 -0
  23. data/ext/libsvm/java/libsvm/svm_parameter.java +47 -0
  24. data/ext/libsvm/java/libsvm/svm_print_interface.java +5 -0
  25. data/ext/libsvm/java/libsvm/svm_problem.java +7 -0
  26. data/ext/libsvm/java/svm_predict.java +163 -0
  27. data/ext/libsvm/java/svm_scale.java +350 -0
  28. data/ext/libsvm/java/svm_toy.java +471 -0
  29. data/ext/libsvm/java/svm_train.java +318 -0
  30. data/ext/libsvm/java/test_applet.html +1 -0
  31. data/ext/libsvm/python/Makefile +4 -0
  32. data/ext/libsvm/python/README +331 -0
  33. data/ext/libsvm/python/svm.py +259 -0
  34. data/ext/libsvm/python/svmutil.py +242 -0
  35. data/ext/libsvm/svm-predict.c +226 -0
  36. data/ext/libsvm/svm-scale.c +353 -0
  37. data/ext/libsvm/svm-toy/gtk/Makefile +22 -0
  38. data/ext/libsvm/svm-toy/gtk/callbacks.cpp +423 -0
  39. data/ext/libsvm/svm-toy/gtk/callbacks.h +54 -0
  40. data/ext/libsvm/svm-toy/gtk/interface.c +164 -0
  41. data/ext/libsvm/svm-toy/gtk/interface.h +14 -0
  42. data/ext/libsvm/svm-toy/gtk/main.c +23 -0
  43. data/ext/libsvm/svm-toy/gtk/svm-toy.glade +238 -0
  44. data/ext/libsvm/svm-toy/qt/Makefile +17 -0
  45. data/ext/libsvm/svm-toy/qt/svm-toy.cpp +413 -0
  46. data/ext/libsvm/svm-toy/windows/svm-toy.cpp +456 -0
  47. data/ext/libsvm/svm-train.c +376 -0
  48. data/ext/libsvm/svm.cpp +3060 -0
  49. data/ext/libsvm/svm.def +19 -0
  50. data/ext/libsvm/svm.h +105 -0
  51. data/ext/libsvm/svm.o +0 -0
  52. data/ext/libsvm/tools/README +149 -0
  53. data/ext/libsvm/tools/checkdata.py +108 -0
  54. data/ext/libsvm/tools/easy.py +79 -0
  55. data/ext/libsvm/tools/grid.py +359 -0
  56. data/ext/libsvm/tools/subset.py +146 -0
  57. data/ext/libsvm/windows/libsvm.dll +0 -0
  58. data/ext/libsvm/windows/svm-predict.exe +0 -0
  59. data/ext/libsvm/windows/svm-scale.exe +0 -0
  60. data/ext/libsvm/windows/svm-toy.exe +0 -0
  61. data/ext/libsvm/windows/svm-train.exe +0 -0
  62. data/lib/eluka.rb +10 -0
  63. data/lib/eluka/bijection.rb +23 -0
  64. data/lib/eluka/data_point.rb +36 -0
  65. data/lib/eluka/document.rb +47 -0
  66. data/lib/eluka/feature_vector.rb +86 -0
  67. data/lib/eluka/features.rb +31 -0
  68. data/lib/eluka/model.rb +129 -0
  69. data/lib/fselect.rb +321 -0
  70. data/lib/grid.rb +25 -0
  71. data/test/helper.rb +18 -0
  72. data/test/test_eluka.rb +7 -0
  73. metadata +214 -0
@@ -0,0 +1,413 @@
1
+ #include <QtGui>
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <ctype.h>
5
+ #include <list>
6
+ #include "../../svm.h"
7
+ using namespace std;
8
+
9
+ #define DEFAULT_PARAM "-t 2 -c 100"
10
+ #define XLEN 500
11
+ #define YLEN 500
12
+
13
+ QRgb colors[] =
14
+ {
15
+ qRgb(0,0,0),
16
+ qRgb(0,120,120),
17
+ qRgb(120,120,0),
18
+ qRgb(120,0,120),
19
+ qRgb(0,200,200),
20
+ qRgb(200,200,0),
21
+ qRgb(200,0,200)
22
+ };
23
+
24
+ class SvmToyWindow : public QWidget
25
+ {
26
+
27
+ Q_OBJECT
28
+
29
+ public:
30
+ SvmToyWindow();
31
+ ~SvmToyWindow();
32
+ protected:
33
+ virtual void mousePressEvent( QMouseEvent* );
34
+ virtual void paintEvent( QPaintEvent* );
35
+
36
+ private:
37
+ QPixmap buffer;
38
+ QPixmap icon1;
39
+ QPixmap icon2;
40
+ QPixmap icon3;
41
+ QPushButton button_change_icon;
42
+ QPushButton button_run;
43
+ QPushButton button_clear;
44
+ QPushButton button_save;
45
+ QPushButton button_load;
46
+ QLineEdit input_line;
47
+ QPainter buffer_painter;
48
+ struct point {
49
+ double x, y;
50
+ signed char value;
51
+ };
52
+ list<point> point_list;
53
+ int current_value;
54
+ const QPixmap& choose_icon(int v)
55
+ {
56
+ if(v==1) return icon1;
57
+ else if(v==2) return icon2;
58
+ else return icon3;
59
+ }
60
+ void clear_all()
61
+ {
62
+ point_list.clear();
63
+ buffer.fill(Qt::black);
64
+ repaint();
65
+ }
66
+ void draw_point(const point& p)
67
+ {
68
+ const QPixmap& icon = choose_icon(p.value);
69
+ buffer_painter.drawPixmap((int)(p.x*XLEN),(int)(p.y*YLEN),icon);
70
+ repaint();
71
+ }
72
+ void draw_all_points()
73
+ {
74
+ for(list<point>::iterator p = point_list.begin(); p != point_list.end();p++)
75
+ draw_point(*p);
76
+ }
77
+ private slots:
78
+ void button_change_icon_clicked()
79
+ {
80
+ ++current_value;
81
+ if(current_value > 3) current_value = 1;
82
+ button_change_icon.setIcon(choose_icon(current_value));
83
+ }
84
+ void button_run_clicked()
85
+ {
86
+ // guard
87
+ if(point_list.empty()) return;
88
+
89
+ svm_parameter param;
90
+ int i,j;
91
+
92
+ // default values
93
+ param.svm_type = C_SVC;
94
+ param.kernel_type = RBF;
95
+ param.degree = 3;
96
+ param.gamma = 0;
97
+ param.coef0 = 0;
98
+ param.nu = 0.5;
99
+ param.cache_size = 100;
100
+ param.C = 1;
101
+ param.eps = 1e-3;
102
+ param.p = 0.1;
103
+ param.shrinking = 1;
104
+ param.probability = 0;
105
+ param.nr_weight = 0;
106
+ param.weight_label = NULL;
107
+ param.weight = NULL;
108
+
109
+ // parse options
110
+ const char *p = input_line.text().toAscii().constData();
111
+
112
+ while (1) {
113
+ while (*p && *p != '-')
114
+ p++;
115
+
116
+ if (*p == '\0')
117
+ break;
118
+
119
+ p++;
120
+ switch (*p++) {
121
+ case 's':
122
+ param.svm_type = atoi(p);
123
+ break;
124
+ case 't':
125
+ param.kernel_type = atoi(p);
126
+ break;
127
+ case 'd':
128
+ param.degree = atoi(p);
129
+ break;
130
+ case 'g':
131
+ param.gamma = atof(p);
132
+ break;
133
+ case 'r':
134
+ param.coef0 = atof(p);
135
+ break;
136
+ case 'n':
137
+ param.nu = atof(p);
138
+ break;
139
+ case 'm':
140
+ param.cache_size = atof(p);
141
+ break;
142
+ case 'c':
143
+ param.C = atof(p);
144
+ break;
145
+ case 'e':
146
+ param.eps = atof(p);
147
+ break;
148
+ case 'p':
149
+ param.p = atof(p);
150
+ break;
151
+ case 'h':
152
+ param.shrinking = atoi(p);
153
+ break;
154
+ case 'b':
155
+ param.probability = atoi(p);
156
+ break;
157
+ case 'w':
158
+ ++param.nr_weight;
159
+ param.weight_label = (int *)realloc(param.weight_label,sizeof(int)*param.nr_weight);
160
+ param.weight = (double *)realloc(param.weight,sizeof(double)*param.nr_weight);
161
+ param.weight_label[param.nr_weight-1] = atoi(p);
162
+ while(*p && !isspace(*p)) ++p;
163
+ param.weight[param.nr_weight-1] = atof(p);
164
+ break;
165
+ }
166
+ }
167
+
168
+ // build problem
169
+ svm_problem prob;
170
+
171
+ prob.l = point_list.size();
172
+ prob.y = new double[prob.l];
173
+
174
+ if(param.kernel_type == PRECOMPUTED)
175
+ {
176
+ }
177
+ else if(param.svm_type == EPSILON_SVR ||
178
+ param.svm_type == NU_SVR)
179
+ {
180
+ if(param.gamma == 0) param.gamma = 1;
181
+ svm_node *x_space = new svm_node[2 * prob.l];
182
+ prob.x = new svm_node *[prob.l];
183
+
184
+ i = 0;
185
+ for (list <point>::iterator q = point_list.begin(); q != point_list.end(); q++, i++)
186
+ {
187
+ x_space[2 * i].index = 1;
188
+ x_space[2 * i].value = q->x;
189
+ x_space[2 * i + 1].index = -1;
190
+ prob.x[i] = &x_space[2 * i];
191
+ prob.y[i] = q->y;
192
+ }
193
+
194
+ // build model & classify
195
+ svm_model *model = svm_train(&prob, &param);
196
+ svm_node x[2];
197
+ x[0].index = 1;
198
+ x[1].index = -1;
199
+ int *j = new int[XLEN];
200
+
201
+ for (i = 0; i < XLEN; i++)
202
+ {
203
+ x[0].value = (double) i / XLEN;
204
+ j[i] = (int)(YLEN*svm_predict(model, x));
205
+ }
206
+
207
+ buffer_painter.setPen(colors[0]);
208
+ buffer_painter.drawLine(0,0,0,YLEN-1);
209
+
210
+ int p = (int)(param.p * YLEN);
211
+ for(i = 1; i < XLEN; i++)
212
+ {
213
+ buffer_painter.setPen(colors[0]);
214
+ buffer_painter.drawLine(i,0,i,YLEN-1);
215
+
216
+ buffer_painter.setPen(colors[5]);
217
+ buffer_painter.drawLine(i-1,j[i-1],i,j[i]);
218
+
219
+ if(param.svm_type == EPSILON_SVR)
220
+ {
221
+ buffer_painter.setPen(colors[2]);
222
+ buffer_painter.drawLine(i-1,j[i-1]+p,i,j[i]+p);
223
+
224
+ buffer_painter.setPen(colors[2]);
225
+ buffer_painter.drawLine(i-1,j[i-1]-p,i,j[i]-p);
226
+ }
227
+ }
228
+
229
+ svm_free_and_destroy_model(&model);
230
+ delete[] j;
231
+ delete[] x_space;
232
+ delete[] prob.x;
233
+ delete[] prob.y;
234
+ }
235
+ else
236
+ {
237
+ if(param.gamma == 0) param.gamma = 0.5;
238
+ svm_node *x_space = new svm_node[3 * prob.l];
239
+ prob.x = new svm_node *[prob.l];
240
+
241
+ i = 0;
242
+ for (list <point>::iterator q = point_list.begin(); q != point_list.end(); q++, i++)
243
+ {
244
+ x_space[3 * i].index = 1;
245
+ x_space[3 * i].value = q->x;
246
+ x_space[3 * i + 1].index = 2;
247
+ x_space[3 * i + 1].value = q->y;
248
+ x_space[3 * i + 2].index = -1;
249
+ prob.x[i] = &x_space[3 * i];
250
+ prob.y[i] = q->value;
251
+ }
252
+
253
+ // build model & classify
254
+ svm_model *model = svm_train(&prob, &param);
255
+ svm_node x[3];
256
+ x[0].index = 1;
257
+ x[1].index = 2;
258
+ x[2].index = -1;
259
+
260
+ for (i = 0; i < XLEN; i++)
261
+ for (j = 0; j < YLEN ; j++) {
262
+ x[0].value = (double) i / XLEN;
263
+ x[1].value = (double) j / YLEN;
264
+ double d = svm_predict(model, x);
265
+ if (param.svm_type == ONE_CLASS && d<0) d=2;
266
+ buffer_painter.setPen(colors[(int)d]);
267
+ buffer_painter.drawPoint(i,j);
268
+ }
269
+
270
+ svm_free_and_destroy_model(&model);
271
+ delete[] x_space;
272
+ delete[] prob.x;
273
+ delete[] prob.y;
274
+ }
275
+ free(param.weight_label);
276
+ free(param.weight);
277
+ draw_all_points();
278
+ }
279
+ void button_clear_clicked()
280
+ {
281
+ clear_all();
282
+ }
283
+ void button_save_clicked()
284
+ {
285
+ QString filename = QFileDialog::getSaveFileName();
286
+ if(!filename.isNull())
287
+ {
288
+ FILE *fp = fopen(filename.toAscii().constData(),"w");
289
+ if(fp)
290
+ {
291
+ for(list<point>::iterator p = point_list.begin(); p != point_list.end();p++)
292
+ fprintf(fp,"%d 1:%f 2:%f\n", p->value, p->x, p->y);
293
+ fclose(fp);
294
+ }
295
+ }
296
+ }
297
+ void button_load_clicked()
298
+ {
299
+ QString filename = QFileDialog::getOpenFileName();
300
+ if(!filename.isNull())
301
+ {
302
+ FILE *fp = fopen(filename.toAscii().constData(),"r");
303
+ if(fp)
304
+ {
305
+ clear_all();
306
+ char buf[4096];
307
+ while(fgets(buf,sizeof(buf),fp))
308
+ {
309
+ int v;
310
+ double x,y;
311
+ if(sscanf(buf,"%d%*d:%lf%*d:%lf",&v,&x,&y)!=3)
312
+ break;
313
+ point p = {x,y,v};
314
+ point_list.push_back(p);
315
+ }
316
+ fclose(fp);
317
+ draw_all_points();
318
+ }
319
+ }
320
+
321
+ }
322
+ };
323
+
324
+ #include "svm-toy.moc"
325
+
326
+ SvmToyWindow::SvmToyWindow()
327
+ :button_change_icon(this)
328
+ ,button_run("Run",this)
329
+ ,button_clear("Clear",this)
330
+ ,button_save("Save",this)
331
+ ,button_load("Load",this)
332
+ ,input_line(this)
333
+ ,current_value(1)
334
+ {
335
+ buffer = QPixmap(XLEN,YLEN);
336
+ buffer.fill(Qt::black);
337
+
338
+ buffer_painter.begin(&buffer);
339
+
340
+ QObject::connect(&button_change_icon, SIGNAL(clicked()), this,
341
+ SLOT(button_change_icon_clicked()));
342
+ QObject::connect(&button_run, SIGNAL(clicked()), this,
343
+ SLOT(button_run_clicked()));
344
+ QObject::connect(&button_clear, SIGNAL(clicked()), this,
345
+ SLOT(button_clear_clicked()));
346
+ QObject::connect(&button_save, SIGNAL(clicked()), this,
347
+ SLOT(button_save_clicked()));
348
+ QObject::connect(&button_load, SIGNAL(clicked()), this,
349
+ SLOT(button_load_clicked()));
350
+ QObject::connect(&input_line, SIGNAL(returnPressed()), this,
351
+ SLOT(button_run_clicked()));
352
+
353
+ // don't blank the window before repainting
354
+ setAttribute(Qt::WA_NoBackground);
355
+
356
+ icon1 = QPixmap(4,4);
357
+ icon2 = QPixmap(4,4);
358
+ icon3 = QPixmap(4,4);
359
+
360
+
361
+ QPainter painter;
362
+ painter.begin(&icon1);
363
+ painter.fillRect(0,0,4,4,QBrush(colors[4]));
364
+ painter.end();
365
+
366
+ painter.begin(&icon2);
367
+ painter.fillRect(0,0,4,4,QBrush(colors[5]));
368
+ painter.end();
369
+
370
+ painter.begin(&icon3);
371
+ painter.fillRect(0,0,4,4,QBrush(colors[6]));
372
+ painter.end();
373
+
374
+ button_change_icon.setGeometry( 0, YLEN, 50, 25 );
375
+ button_run.setGeometry( 50, YLEN, 50, 25 );
376
+ button_clear.setGeometry( 100, YLEN, 50, 25 );
377
+ button_save.setGeometry( 150, YLEN, 50, 25);
378
+ button_load.setGeometry( 200, YLEN, 50, 25);
379
+ input_line.setGeometry( 250, YLEN, 250, 25);
380
+
381
+ input_line.setText(DEFAULT_PARAM);
382
+ button_change_icon.setIcon(icon1);
383
+ }
384
+
385
+ SvmToyWindow::~SvmToyWindow()
386
+ {
387
+ buffer_painter.end();
388
+ }
389
+
390
+ void SvmToyWindow::mousePressEvent( QMouseEvent* event )
391
+ {
392
+ point p = {(double)event->x()/XLEN, (double)event->y()/YLEN, current_value};
393
+ point_list.push_back(p);
394
+ draw_point(p);
395
+ }
396
+
397
+ void SvmToyWindow::paintEvent( QPaintEvent* )
398
+ {
399
+ // copy the image from the buffer pixmap to the window
400
+ QPainter p(this);
401
+ p.drawPixmap(0, 0, buffer);
402
+ }
403
+
404
+ int main( int argc, char* argv[] )
405
+ {
406
+ QApplication myapp( argc, argv );
407
+
408
+ SvmToyWindow* mywidget = new SvmToyWindow();
409
+ mywidget->setGeometry( 100, 100, XLEN, YLEN+25 );
410
+
411
+ mywidget->show();
412
+ return myapp.exec();
413
+ }
@@ -0,0 +1,456 @@
1
+ #include <windows.h>
2
+ #include <windowsx.h>
3
+ #include <stdio.h>
4
+ #include <ctype.h>
5
+ #include <list>
6
+ #include "../../svm.h"
7
+ using namespace std;
8
+
9
+ #define DEFAULT_PARAM "-t 2 -c 100"
10
+ #define XLEN 500
11
+ #define YLEN 500
12
+ #define DrawLine(dc,x1,y1,x2,y2,c) \
13
+ do { \
14
+ HPEN hpen = CreatePen(PS_SOLID,0,c); \
15
+ HPEN horig = SelectPen(dc,hpen); \
16
+ MoveToEx(dc,x1,y1,NULL); \
17
+ LineTo(dc,x2,y2); \
18
+ SelectPen(dc,horig); \
19
+ DeletePen(hpen); \
20
+ } while(0)
21
+
22
+ using namespace std;
23
+
24
+ COLORREF colors[] =
25
+ {
26
+ RGB(0,0,0),
27
+ RGB(0,120,120),
28
+ RGB(120,120,0),
29
+ RGB(120,0,120),
30
+ RGB(0,200,200),
31
+ RGB(200,200,0),
32
+ RGB(200,0,200)
33
+ };
34
+
35
+ HWND main_window;
36
+ HBITMAP buffer;
37
+ HDC window_dc;
38
+ HDC buffer_dc;
39
+ HBRUSH brush1, brush2, brush3;
40
+ HWND edit;
41
+
42
+ enum {
43
+ ID_BUTTON_CHANGE, ID_BUTTON_RUN, ID_BUTTON_CLEAR,
44
+ ID_BUTTON_LOAD, ID_BUTTON_SAVE, ID_EDIT
45
+ };
46
+
47
+ struct point {
48
+ double x, y;
49
+ signed char value;
50
+ };
51
+
52
+ list<point> point_list;
53
+ int current_value = 1;
54
+
55
+ LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
56
+
57
+ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
58
+ PSTR szCmdLine, int iCmdShow)
59
+ {
60
+ static char szAppName[] = "SvmToy";
61
+ MSG msg;
62
+ WNDCLASSEX wndclass;
63
+
64
+ wndclass.cbSize = sizeof(wndclass);
65
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
66
+ wndclass.lpfnWndProc = WndProc;
67
+ wndclass.cbClsExtra = 0;
68
+ wndclass.cbWndExtra = 0;
69
+ wndclass.hInstance = hInstance;
70
+ wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
71
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
72
+ wndclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
73
+ wndclass.lpszMenuName = NULL;
74
+ wndclass.lpszClassName = szAppName;
75
+ wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
76
+
77
+ RegisterClassEx(&wndclass);
78
+
79
+ main_window = CreateWindow(szAppName, // window class name
80
+ "SVM Toy", // window caption
81
+ WS_OVERLAPPEDWINDOW,// window style
82
+ CW_USEDEFAULT, // initial x position
83
+ CW_USEDEFAULT, // initial y position
84
+ XLEN, // initial x size
85
+ YLEN+52, // initial y size
86
+ NULL, // parent window handle
87
+ NULL, // window menu handle
88
+ hInstance, // program instance handle
89
+ NULL); // creation parameters
90
+
91
+ ShowWindow(main_window, iCmdShow);
92
+ UpdateWindow(main_window);
93
+
94
+ CreateWindow("button", "Change", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
95
+ 0, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_CHANGE, hInstance, NULL);
96
+ CreateWindow("button", "Run", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
97
+ 50, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_RUN, hInstance, NULL);
98
+ CreateWindow("button", "Clear", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
99
+ 100, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_CLEAR, hInstance, NULL);
100
+ CreateWindow("button", "Save", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
101
+ 150, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_SAVE, hInstance, NULL);
102
+ CreateWindow("button", "Load", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
103
+ 200, YLEN, 50, 25, main_window, (HMENU) ID_BUTTON_LOAD, hInstance, NULL);
104
+
105
+ edit = CreateWindow("edit", NULL, WS_CHILD | WS_VISIBLE,
106
+ 250, YLEN, 250, 25, main_window, (HMENU) ID_EDIT, hInstance, NULL);
107
+
108
+ Edit_SetText(edit,DEFAULT_PARAM);
109
+
110
+ brush1 = CreateSolidBrush(colors[4]);
111
+ brush2 = CreateSolidBrush(colors[5]);
112
+ brush3 = CreateSolidBrush(colors[6]);
113
+
114
+ window_dc = GetDC(main_window);
115
+ buffer = CreateCompatibleBitmap(window_dc, XLEN, YLEN);
116
+ buffer_dc = CreateCompatibleDC(window_dc);
117
+ SelectObject(buffer_dc, buffer);
118
+ PatBlt(buffer_dc, 0, 0, XLEN, YLEN, BLACKNESS);
119
+
120
+ while (GetMessage(&msg, NULL, 0, 0)) {
121
+ TranslateMessage(&msg);
122
+ DispatchMessage(&msg);
123
+ }
124
+ return msg.wParam;
125
+ }
126
+
127
+ int getfilename( HWND hWnd , char *filename, int len, int save)
128
+ {
129
+ OPENFILENAME OpenFileName;
130
+ memset(&OpenFileName,0,sizeof(OpenFileName));
131
+ filename[0]='\0';
132
+
133
+ OpenFileName.lStructSize = sizeof(OPENFILENAME);
134
+ OpenFileName.hwndOwner = hWnd;
135
+ OpenFileName.lpstrFile = filename;
136
+ OpenFileName.nMaxFile = len;
137
+ OpenFileName.Flags = 0;
138
+
139
+ return save?GetSaveFileName(&OpenFileName):GetOpenFileName(&OpenFileName);
140
+ }
141
+
142
+ void clear_all()
143
+ {
144
+ point_list.clear();
145
+ PatBlt(buffer_dc, 0, 0, XLEN, YLEN, BLACKNESS);
146
+ InvalidateRect(main_window, 0, 0);
147
+ }
148
+
149
+ HBRUSH choose_brush(int v)
150
+ {
151
+ if(v==1) return brush1;
152
+ else if(v==2) return brush2;
153
+ else return brush3;
154
+ }
155
+
156
+ void draw_point(const point & p)
157
+ {
158
+ RECT rect;
159
+ rect.left = int(p.x*XLEN);
160
+ rect.top = int(p.y*YLEN);
161
+ rect.right = int(p.x*XLEN) + 3;
162
+ rect.bottom = int(p.y*YLEN) + 3;
163
+ FillRect(window_dc, &rect, choose_brush(p.value));
164
+ FillRect(buffer_dc, &rect, choose_brush(p.value));
165
+ }
166
+
167
+ void draw_all_points()
168
+ {
169
+ for(list<point>::iterator p = point_list.begin(); p != point_list.end(); p++)
170
+ draw_point(*p);
171
+ }
172
+
173
+ void button_run_clicked()
174
+ {
175
+ // guard
176
+ if(point_list.empty()) return;
177
+
178
+ svm_parameter param;
179
+ int i,j;
180
+
181
+ // default values
182
+ param.svm_type = C_SVC;
183
+ param.kernel_type = RBF;
184
+ param.degree = 3;
185
+ param.gamma = 0;
186
+ param.coef0 = 0;
187
+ param.nu = 0.5;
188
+ param.cache_size = 100;
189
+ param.C = 1;
190
+ param.eps = 1e-3;
191
+ param.p = 0.1;
192
+ param.shrinking = 1;
193
+ param.probability = 0;
194
+ param.nr_weight = 0;
195
+ param.weight_label = NULL;
196
+ param.weight = NULL;
197
+
198
+ // parse options
199
+ char str[1024];
200
+ Edit_GetLine(edit, 0, str, sizeof(str));
201
+ const char *p = str;
202
+
203
+ while (1) {
204
+ while (*p && *p != '-')
205
+ p++;
206
+
207
+ if (*p == '\0')
208
+ break;
209
+
210
+ p++;
211
+ switch (*p++) {
212
+ case 's':
213
+ param.svm_type = atoi(p);
214
+ break;
215
+ case 't':
216
+ param.kernel_type = atoi(p);
217
+ break;
218
+ case 'd':
219
+ param.degree = atoi(p);
220
+ break;
221
+ case 'g':
222
+ param.gamma = atof(p);
223
+ break;
224
+ case 'r':
225
+ param.coef0 = atof(p);
226
+ break;
227
+ case 'n':
228
+ param.nu = atof(p);
229
+ break;
230
+ case 'm':
231
+ param.cache_size = atof(p);
232
+ break;
233
+ case 'c':
234
+ param.C = atof(p);
235
+ break;
236
+ case 'e':
237
+ param.eps = atof(p);
238
+ break;
239
+ case 'p':
240
+ param.p = atof(p);
241
+ break;
242
+ case 'h':
243
+ param.shrinking = atoi(p);
244
+ break;
245
+ case 'b':
246
+ param.probability = atoi(p);
247
+ break;
248
+ case 'w':
249
+ ++param.nr_weight;
250
+ param.weight_label = (int *)realloc(param.weight_label,sizeof(int)*param.nr_weight);
251
+ param.weight = (double *)realloc(param.weight,sizeof(double)*param.nr_weight);
252
+ param.weight_label[param.nr_weight-1] = atoi(p);
253
+ while(*p && !isspace(*p)) ++p;
254
+ param.weight[param.nr_weight-1] = atof(p);
255
+ break;
256
+ }
257
+ }
258
+
259
+ // build problem
260
+ svm_problem prob;
261
+
262
+ prob.l = point_list.size();
263
+ prob.y = new double[prob.l];
264
+
265
+ if(param.kernel_type == PRECOMPUTED)
266
+ {
267
+ }
268
+ else if(param.svm_type == EPSILON_SVR ||
269
+ param.svm_type == NU_SVR)
270
+ {
271
+ if(param.gamma == 0) param.gamma = 1;
272
+ svm_node *x_space = new svm_node[2 * prob.l];
273
+ prob.x = new svm_node *[prob.l];
274
+
275
+ i = 0;
276
+ for (list<point>::iterator q = point_list.begin(); q != point_list.end(); q++, i++)
277
+ {
278
+ x_space[2 * i].index = 1;
279
+ x_space[2 * i].value = q->x;
280
+ x_space[2 * i + 1].index = -1;
281
+ prob.x[i] = &x_space[2 * i];
282
+ prob.y[i] = q->y;
283
+ }
284
+
285
+ // build model & classify
286
+ svm_model *model = svm_train(&prob, &param);
287
+ svm_node x[2];
288
+ x[0].index = 1;
289
+ x[1].index = -1;
290
+ int *j = new int[XLEN];
291
+
292
+ for (i = 0; i < XLEN; i++)
293
+ {
294
+ x[0].value = (double) i / XLEN;
295
+ j[i] = (int)(YLEN*svm_predict(model, x));
296
+ }
297
+
298
+ DrawLine(buffer_dc,0,0,0,YLEN,colors[0]);
299
+ DrawLine(window_dc,0,0,0,YLEN,colors[0]);
300
+
301
+ int p = (int)(param.p * YLEN);
302
+ for(int i=1; i < XLEN; i++)
303
+ {
304
+ DrawLine(buffer_dc,i,0,i,YLEN,colors[0]);
305
+ DrawLine(window_dc,i,0,i,YLEN,colors[0]);
306
+
307
+ DrawLine(buffer_dc,i-1,j[i-1],i,j[i],colors[5]);
308
+ DrawLine(window_dc,i-1,j[i-1],i,j[i],colors[5]);
309
+
310
+ if(param.svm_type == EPSILON_SVR)
311
+ {
312
+ DrawLine(buffer_dc,i-1,j[i-1]+p,i,j[i]+p,colors[2]);
313
+ DrawLine(window_dc,i-1,j[i-1]+p,i,j[i]+p,colors[2]);
314
+
315
+ DrawLine(buffer_dc,i-1,j[i-1]-p,i,j[i]-p,colors[2]);
316
+ DrawLine(window_dc,i-1,j[i-1]-p,i,j[i]-p,colors[2]);
317
+ }
318
+ }
319
+
320
+ svm_free_and_destroy_model(&model);
321
+ delete[] j;
322
+ delete[] x_space;
323
+ delete[] prob.x;
324
+ delete[] prob.y;
325
+ }
326
+ else
327
+ {
328
+ if(param.gamma == 0) param.gamma = 0.5;
329
+ svm_node *x_space = new svm_node[3 * prob.l];
330
+ prob.x = new svm_node *[prob.l];
331
+
332
+ i = 0;
333
+ for (list<point>::iterator q = point_list.begin(); q != point_list.end(); q++, i++)
334
+ {
335
+ x_space[3 * i].index = 1;
336
+ x_space[3 * i].value = q->x;
337
+ x_space[3 * i + 1].index = 2;
338
+ x_space[3 * i + 1].value = q->y;
339
+ x_space[3 * i + 2].index = -1;
340
+ prob.x[i] = &x_space[3 * i];
341
+ prob.y[i] = q->value;
342
+ }
343
+
344
+ // build model & classify
345
+ svm_model *model = svm_train(&prob, &param);
346
+ svm_node x[3];
347
+ x[0].index = 1;
348
+ x[1].index = 2;
349
+ x[2].index = -1;
350
+
351
+ for (i = 0; i < XLEN; i++)
352
+ for (j = 0; j < YLEN; j++) {
353
+ x[0].value = (double) i / XLEN;
354
+ x[1].value = (double) j / YLEN;
355
+ double d = svm_predict(model, x);
356
+ if (param.svm_type == ONE_CLASS && d<0) d=2;
357
+ SetPixel(window_dc, i, j, colors[(int)d]);
358
+ SetPixel(buffer_dc, i, j, colors[(int)d]);
359
+ }
360
+
361
+ svm_free_and_destroy_model(&model);
362
+ delete[] x_space;
363
+ delete[] prob.x;
364
+ delete[] prob.y;
365
+ }
366
+ free(param.weight_label);
367
+ free(param.weight);
368
+ draw_all_points();
369
+ }
370
+
371
+ LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
372
+ {
373
+ HDC hdc;
374
+ PAINTSTRUCT ps;
375
+
376
+ switch (iMsg) {
377
+ case WM_LBUTTONDOWN:
378
+ {
379
+ int x = LOWORD(lParam);
380
+ int y = HIWORD(lParam);
381
+ point p = {(double)x/XLEN, (double)y/YLEN, current_value};
382
+ point_list.push_back(p);
383
+ draw_point(p);
384
+ }
385
+ return 0;
386
+ case WM_PAINT:
387
+ {
388
+ hdc = BeginPaint(hwnd, &ps);
389
+ BitBlt(hdc, 0, 0, XLEN, YLEN, buffer_dc, 0, 0, SRCCOPY);
390
+ EndPaint(hwnd, &ps);
391
+ }
392
+ return 0;
393
+ case WM_COMMAND:
394
+ {
395
+ int id = LOWORD(wParam);
396
+ switch (id) {
397
+ case ID_BUTTON_CHANGE:
398
+ ++current_value;
399
+ if(current_value > 3) current_value = 1;
400
+ break;
401
+ case ID_BUTTON_RUN:
402
+ button_run_clicked();
403
+ break;
404
+ case ID_BUTTON_CLEAR:
405
+ clear_all();
406
+ break;
407
+ case ID_BUTTON_SAVE:
408
+ {
409
+ char filename[1024];
410
+ if(getfilename(hwnd,filename,1024,1))
411
+ {
412
+ FILE *fp = fopen(filename,"w");
413
+ if(fp)
414
+ {
415
+ for (list<point>::iterator p = point_list.begin(); p != point_list.end(); p++)
416
+ fprintf(fp,"%d 1:%f 2:%f\n",p->value,p->x,p->y);
417
+ fclose(fp);
418
+ }
419
+ }
420
+ }
421
+ break;
422
+ case ID_BUTTON_LOAD:
423
+ {
424
+ char filename[1024];
425
+ if(getfilename(hwnd,filename,1024,0))
426
+ {
427
+ FILE *fp = fopen(filename,"r");
428
+ if(fp)
429
+ {
430
+ clear_all();
431
+ char buf[4096];
432
+ while(fgets(buf,sizeof(buf),fp))
433
+ {
434
+ int v;
435
+ double x,y;
436
+ if(sscanf(buf,"%d%*d:%lf%*d:%lf",&v,&x,&y)!=3)
437
+ break;
438
+ point p = {x,y,v};
439
+ point_list.push_back(p);
440
+ }
441
+ fclose(fp);
442
+ draw_all_points();
443
+ }
444
+ }
445
+ }
446
+ break;
447
+ }
448
+ }
449
+ return 0;
450
+ case WM_DESTROY:
451
+ PostQuitMessage(0);
452
+ return 0;
453
+ }
454
+
455
+ return DefWindowProc(hwnd, iMsg, wParam, lParam);
456
+ }