svm-toy.cpp
上传用户:xgw_05
上传日期:2014-12-08
资源大小:2726k
文件大小:10k
源码类别:

.net编程

开发平台:

Java

  1. #include <qapplication.h>
  2. #include <qpainter.h>
  3. #include <qpixmap.h>
  4. #include <qwidget.h>
  5. #include <qpushbutton.h>
  6. #include <qlineedit.h>
  7. #include <qfiledialog.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #include <list>
  12. #include "../../svm.h"
  13. #define DEFAULT_PARAM "-t 2 -c 100"
  14. #define XLEN 500
  15. #define YLEN 500
  16. QRgb colors[] =
  17. {
  18. qRgb(0,0,0),
  19. qRgb(0,120,120),
  20. qRgb(120,120,0),
  21. qRgb(120,0,120),
  22. qRgb(0,200,200),
  23. qRgb(200,200,0),
  24. qRgb(200,0,200)
  25. };
  26. class SvmToyWindow : public QWidget
  27. {
  28. Q_OBJECT
  29. public:
  30. SvmToyWindow();
  31. ~SvmToyWindow();
  32. protected:
  33. virtual void mousePressEvent( QMouseEvent* );
  34. virtual void paintEvent( QPaintEvent* );
  35. private:
  36. QPixmap buffer;
  37. QPixmap icon1;
  38. QPixmap icon2;
  39. QPixmap icon3;
  40. QPushButton button_change_icon;
  41. QPushButton button_run;
  42. QPushButton button_clear;
  43. QPushButton button_save;
  44. QPushButton button_load;
  45. QLineEdit input_line;
  46. QPainter window_painter;
  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(black);
  64. paintEvent(NULL);
  65. }
  66. void draw_point(const point& p)
  67. {
  68. const QPixmap& icon = choose_icon(p.value);
  69. window_painter.drawPixmap((int)(p.x*XLEN),(int)(p.y*YLEN),icon);
  70. buffer_painter.drawPixmap((int)(p.x*XLEN),(int)(p.y*YLEN),icon);
  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.setPixmap(choose_icon(current_value));
  83. }
  84. void button_run_clicked()
  85. {
  86. // guard
  87. if(point_list.empty()) return;
  88. svm_parameter param;
  89. int i,j;
  90. // default values
  91. param.svm_type = C_SVC;
  92. param.kernel_type = RBF;
  93. param.degree = 3;
  94. param.gamma = 0;
  95. param.coef0 = 0;
  96. param.nu = 0.5;
  97. param.cache_size = 40;
  98. param.C = 1;
  99. param.eps = 1e-3;
  100. param.p = 0.1;
  101. param.shrinking = 1;
  102. param.nr_weight = 0;
  103. param.weight_label = NULL;
  104. param.weight = NULL;
  105. // parse options
  106. const char *p = input_line.text();
  107. while (1) {
  108. while (*p && *p != '-')
  109. p++;
  110. if (*p == '')
  111. break;
  112. p++;
  113. switch (*p++) {
  114. case 's':
  115. param.svm_type = atoi(p);
  116. break;
  117. case 't':
  118. param.kernel_type = atoi(p);
  119. break;
  120. case 'd':
  121. param.degree = atof(p);
  122. break;
  123. case 'g':
  124. param.gamma = atof(p);
  125. break;
  126. case 'r':
  127. param.coef0 = atof(p);
  128. break;
  129. case 'n':
  130. param.nu = atof(p);
  131. break;
  132. case 'm':
  133. param.cache_size = atof(p);
  134. break;
  135. case 'c':
  136. param.C = atof(p);
  137. break;
  138. case 'e':
  139. param.eps = atof(p);
  140. break;
  141. case 'p':
  142. param.p = atof(p);
  143. break;
  144. case 'h':
  145. param.shrinking = atoi(p);
  146. break;
  147. case 'w':
  148. ++param.nr_weight;
  149. param.weight_label = (int *)realloc(param.weight_label,sizeof(int)*param.nr_weight);
  150. param.weight = (double *)realloc(param.weight,sizeof(double)*param.nr_weight);
  151. param.weight_label[param.nr_weight-1] = atoi(p);
  152. while(*p && !isspace(*p)) ++p;
  153. param.weight[param.nr_weight-1] = atof(p);
  154. break;
  155. }
  156. }
  157. // build problem
  158. svm_problem prob;
  159. prob.l = point_list.size();
  160. prob.y = new double[prob.l];
  161. if(param.svm_type == EPSILON_SVR ||
  162.    param.svm_type == NU_SVR)
  163. {
  164. if(param.gamma == 0) param.gamma = 1;
  165. svm_node *x_space = new svm_node[2 * prob.l];
  166. prob.x = new svm_node *[prob.l];
  167. i = 0;
  168. for (list <point>::iterator q = point_list.begin(); q != point_list.end(); q++, i++)
  169. {
  170. x_space[2 * i].index = 1;
  171. x_space[2 * i].value = q->x;
  172. x_space[2 * i + 1].index = -1;
  173. prob.x[i] = &x_space[2 * i];
  174. prob.y[i] = q->y;
  175. }
  176. // build model & classify
  177. svm_model *model = svm_train(&prob, &param);
  178. svm_node x[2];
  179. x[0].index = 1;
  180. x[1].index = -1;
  181. int *j = new int[XLEN];
  182. for (i = 0; i < XLEN; i++)
  183. {
  184. x[0].value = (double) i / XLEN;
  185. j[i] = (int)(YLEN*svm_predict(model, x));
  186. }
  187. buffer_painter.setPen(colors[0]);
  188. buffer_painter.drawLine(0,0,0,YLEN-1);
  189. window_painter.setPen(colors[0]);
  190. window_painter.drawLine(0,0,0,YLEN-1);
  191. int p = (int)(param.p * YLEN);
  192. for(i = 1; i < XLEN; i++)
  193. {
  194. buffer_painter.setPen(colors[0]);
  195. buffer_painter.drawLine(i,0,i,YLEN-1);
  196. window_painter.setPen(colors[0]);
  197. window_painter.drawLine(i,0,i,YLEN-1);
  198. buffer_painter.setPen(colors[5]);
  199. buffer_painter.drawLine(i-1,j[i-1],i,j[i]);
  200. window_painter.setPen(colors[5]);
  201. window_painter.drawLine(i-1,j[i-1],i,j[i]);
  202. if(param.svm_type == EPSILON_SVR)
  203. {
  204. buffer_painter.setPen(colors[2]);
  205. buffer_painter.drawLine(i-1,j[i-1]+p,i,j[i]+p);
  206. window_painter.setPen(colors[2]);
  207. window_painter.drawLine(i-1,j[i-1]+p,i,j[i]+p);
  208. buffer_painter.setPen(colors[2]);
  209. buffer_painter.drawLine(i-1,j[i-1]-p,i,j[i]-p);
  210. window_painter.setPen(colors[2]);
  211. window_painter.drawLine(i-1,j[i-1]-p,i,j[i]-p);
  212. }
  213. }
  214. svm_destroy_model(model);
  215. delete[] j;
  216. delete[] x_space;
  217. delete[] prob.x;
  218. delete[] prob.y;
  219. }
  220. else
  221. {
  222. if(param.gamma == 0) param.gamma = 0.5;
  223. svm_node *x_space = new svm_node[3 * prob.l];
  224. prob.x = new svm_node *[prob.l];
  225. i = 0;
  226. for (list <point>::iterator q = point_list.begin(); q != point_list.end(); q++, i++)
  227. {
  228. x_space[3 * i].index = 1;
  229. x_space[3 * i].value = q->x;
  230. x_space[3 * i + 1].index = 2;
  231. x_space[3 * i + 1].value = q->y;
  232. x_space[3 * i + 2].index = -1;
  233. prob.x[i] = &x_space[3 * i];
  234. prob.y[i] = q->value;
  235. }
  236. // build model & classify
  237. svm_model *model = svm_train(&prob, &param);
  238. svm_node x[3];
  239. x[0].index = 1;
  240. x[1].index = 2;
  241. x[2].index = -1;
  242. for (i = 0; i < XLEN; i++)
  243. for (j = 0; j < YLEN ; j++) {
  244. x[0].value = (double) i / XLEN;
  245. x[1].value = (double) j / YLEN;
  246. double d = svm_predict(model, x);
  247. buffer_painter.setPen(colors[(int)d]);
  248. window_painter.setPen(colors[(int)d]);
  249. buffer_painter.drawPoint(i,j);
  250. window_painter.drawPoint(i,j);
  251. }
  252. svm_destroy_model(model);
  253. delete[] x_space;
  254. delete[] prob.x;
  255. delete[] prob.y;
  256. }
  257. free(param.weight_label);
  258. free(param.weight);
  259. draw_all_points();
  260. }
  261. void button_clear_clicked()
  262. {
  263. clear_all();
  264. }
  265. void button_save_clicked()
  266. {
  267. QString filename = QFileDialog::getSaveFileName();
  268. if(!filename.isNull())
  269. {
  270. FILE *fp = fopen(filename,"w");
  271. if(fp)
  272. {
  273. for(list<point>::iterator p = point_list.begin(); p != point_list.end();p++)
  274. fprintf(fp,"%d 1:%f 2:%fn", p->value, p->x, p->y);
  275. fclose(fp);
  276. }
  277. }
  278. }
  279. void button_load_clicked()
  280. {
  281. QString filename = QFileDialog::getOpenFileName();
  282. if(!filename.isNull())
  283. {
  284. FILE *fp = fopen(filename,"r");
  285. if(fp)
  286. {
  287. clear_all();
  288. char buf[4096];
  289. while(fgets(buf,sizeof(buf),fp))
  290. {
  291. int v;
  292. double x,y;
  293. if(sscanf(buf,"%d%*d:%lf%*d:%lf",&v,&x,&y)!=3)
  294. break;
  295. point p = {x,y,v};
  296. point_list.push_back(p);
  297. }
  298. fclose(fp);
  299. draw_all_points();
  300. }
  301. }
  302. }
  303. };
  304. #include "svm-toy.moc"
  305. SvmToyWindow::SvmToyWindow()
  306. :button_change_icon(this)
  307. ,button_run("Run",this)
  308. ,button_clear("Clear",this)
  309. ,button_save("Save",this)
  310. ,button_load("Load",this)
  311. ,input_line(this)
  312. ,current_value(1)
  313. {
  314. buffer.resize(XLEN,YLEN);
  315. buffer.fill(black);
  316. window_painter.begin(this);
  317. buffer_painter.begin(&buffer);
  318. QObject::connect(&button_change_icon, SIGNAL(clicked()), this,
  319.  SLOT(button_change_icon_clicked()));
  320. QObject::connect(&button_run, SIGNAL(clicked()), this,
  321.  SLOT(button_run_clicked()));
  322. QObject::connect(&button_clear, SIGNAL(clicked()), this,
  323.  SLOT(button_clear_clicked()));
  324. QObject::connect(&button_save, SIGNAL(clicked()), this,
  325.  SLOT(button_save_clicked()));
  326. QObject::connect(&button_load, SIGNAL(clicked()), this,
  327.  SLOT(button_load_clicked()));
  328. QObject::connect(&input_line, SIGNAL(returnPressed()), this,
  329.  SLOT(button_run_clicked()));
  330.    // don't blank the window before repainting
  331. setBackgroundMode( NoBackground );
  332.   
  333. icon1.resize(4,4);
  334. icon2.resize(4,4);
  335. icon3.resize(4,4);
  336. QPainter painter;
  337. painter.begin(&icon1);
  338. painter.fillRect(0,0,4,4,QBrush(colors[4]));
  339. painter.end();
  340. painter.begin(&icon2);
  341. painter.fillRect(0,0,4,4,QBrush(colors[5]));
  342. painter.end();
  343. painter.begin(&icon3);
  344. painter.fillRect(0,0,4,4,QBrush(colors[6]));
  345. painter.end();
  346. button_change_icon.setGeometry( 0, YLEN, 50, 25 );
  347. button_run.setGeometry( 50, YLEN, 50, 25 );
  348. button_clear.setGeometry( 100, YLEN, 50, 25 );
  349. button_save.setGeometry( 150, YLEN, 50, 25);
  350. button_load.setGeometry( 200, YLEN, 50, 25);
  351. input_line.setGeometry( 250, YLEN, 250, 25);
  352. input_line.setText(DEFAULT_PARAM);
  353. button_change_icon.setPixmap(icon1);
  354. }
  355. SvmToyWindow::~SvmToyWindow()
  356. {
  357. window_painter.end();
  358. buffer_painter.end();
  359. }
  360. void SvmToyWindow::mousePressEvent( QMouseEvent* event )
  361. {
  362. point p = {(double)event->x()/XLEN, (double)event->y()/YLEN, current_value};
  363. point_list.push_back(p);
  364. draw_point(p);
  365. }
  366. void SvmToyWindow::paintEvent( QPaintEvent* )
  367. {
  368. // copy the image from the buffer pixmap to the window
  369. bitBlt( this, 0, 0, &buffer );
  370. }
  371. int main( int argc, char* argv[] )
  372. {
  373. QApplication myapp( argc, argv );
  374. SvmToyWindow* mywidget = new SvmToyWindow();
  375. mywidget->setGeometry( 100, 100, XLEN, YLEN+25 );
  376. myapp.setMainWidget( mywidget );
  377. mywidget->show();
  378. return myapp.exec();
  379. }