1 import libsvm.*;
2 import java.applet.*;
3 import java.awt.*;
4 import java.util.*;
5 import java.awt.event.*;
6 import java.io.*;
7 
8 public class svm_toy extends Applet {
9 
10 	static final String DEFAULT_PARAM="-t 2 -c 100";
11 	int XLEN;
12 	int YLEN;
13 
14 	// off-screen buffer
15 
16 	Image buffer;
17 	Graphics buffer_gc;
18 
19 	// pre-allocated colors
20 
21 	final static Color colors[] =
22 	{
23 	  new Color(0,0,0),
24 	  new Color(0,120,120),
25 	  new Color(120,120,0),
26 	  new Color(120,0,120),
27 	  new Color(0,200,200),
28 	  new Color(200,200,0),
29 	  new Color(200,0,200)
30 	};
31 
32 	class point {
point(double x, double y, byte value)33 		point(double x, double y, byte value)
34 		{
35 			this.x = x;
36 			this.y = y;
37 			this.value = value;
38 		}
39 		double x, y;
40 		byte value;
41 	}
42 
43 	Vector<point> point_list = new Vector<point>();
44 	byte current_value = 1;
45 
init()46 	public void init()
47 	{
48 		setSize(getSize());
49 
50 		final Button button_change = new Button("Change");
51 		Button button_run = new Button("Run");
52 		Button button_clear = new Button("Clear");
53 		Button button_save = new Button("Save");
54 		Button button_load = new Button("Load");
55 		final TextField input_line = new TextField(DEFAULT_PARAM);
56 
57 		BorderLayout layout = new BorderLayout();
58 		this.setLayout(layout);
59 
60 		Panel p = new Panel();
61 		GridBagLayout gridbag = new GridBagLayout();
62 		p.setLayout(gridbag);
63 
64 		GridBagConstraints c = new GridBagConstraints();
65 		c.fill = GridBagConstraints.HORIZONTAL;
66 		c.weightx = 1;
67 		c.gridwidth = 1;
68 		gridbag.setConstraints(button_change,c);
69 		gridbag.setConstraints(button_run,c);
70 		gridbag.setConstraints(button_clear,c);
71 		gridbag.setConstraints(button_save,c);
72 		gridbag.setConstraints(button_load,c);
73 		c.weightx = 5;
74 		c.gridwidth = 5;
75 		gridbag.setConstraints(input_line,c);
76 
77 		button_change.setBackground(colors[current_value]);
78 
79 		p.add(button_change);
80 		p.add(button_run);
81 		p.add(button_clear);
82 		p.add(button_save);
83 		p.add(button_load);
84 		p.add(input_line);
85 		this.add(p,BorderLayout.SOUTH);
86 
87 		button_change.addActionListener(new ActionListener()
88 		{ public void actionPerformed (ActionEvent e)
89 		  { button_change_clicked(); button_change.setBackground(colors[current_value]); }});
90 
91 		button_run.addActionListener(new ActionListener()
92 		{ public void actionPerformed (ActionEvent e)
93 		  { button_run_clicked(input_line.getText()); }});
94 
95 		button_clear.addActionListener(new ActionListener()
96 		{ public void actionPerformed (ActionEvent e)
97 		  { button_clear_clicked(); }});
98 
99 		button_save.addActionListener(new ActionListener()
100 		{ public void actionPerformed (ActionEvent e)
101 		  { button_save_clicked(input_line.getText()); }});
102 
103 		button_load.addActionListener(new ActionListener()
104 		{ public void actionPerformed (ActionEvent e)
105 		  { button_load_clicked(); }});
106 
107 		input_line.addActionListener(new ActionListener()
108 		{ public void actionPerformed (ActionEvent e)
109 		  { button_run_clicked(input_line.getText()); }});
110 
111 		this.enableEvents(AWTEvent.MOUSE_EVENT_MASK);
112 	}
113 
draw_point(point p)114 	void draw_point(point p)
115 	{
116 		Color c = colors[p.value+3];
117 
118 		Graphics window_gc = getGraphics();
119 		buffer_gc.setColor(c);
120 		buffer_gc.fillRect((int)(p.x*XLEN),(int)(p.y*YLEN),4,4);
121 		window_gc.setColor(c);
122 		window_gc.fillRect((int)(p.x*XLEN),(int)(p.y*YLEN),4,4);
123 	}
124 
clear_all()125 	void clear_all()
126 	{
127 		point_list.removeAllElements();
128 		if(buffer != null)
129 		{
130 			buffer_gc.setColor(colors[0]);
131 			buffer_gc.fillRect(0,0,XLEN,YLEN);
132 		}
133 		repaint();
134 	}
135 
draw_all_points()136 	void draw_all_points()
137 	{
138 		int n = point_list.size();
139 		for(int i=0;i<n;i++)
140 			draw_point(point_list.elementAt(i));
141 	}
142 
button_change_clicked()143 	void button_change_clicked()
144 	{
145 		++current_value;
146 		if(current_value > 3) current_value = 1;
147 	}
148 
atof(String s)149 	private static double atof(String s)
150 	{
151 		return Double.valueOf(s).doubleValue();
152 	}
153 
atoi(String s)154 	private static int atoi(String s)
155 	{
156 		return Integer.parseInt(s);
157 	}
158 
button_run_clicked(String args)159 	void button_run_clicked(String args)
160 	{
161 		// guard
162 		if(point_list.isEmpty()) return;
163 
164 		svm_parameter param = new svm_parameter();
165 
166 		// default values
167 		param.svm_type = svm_parameter.C_SVC;
168 		param.kernel_type = svm_parameter.RBF;
169 		param.degree = 3;
170 		param.gamma = 0;
171 		param.coef0 = 0;
172 		param.nu = 0.5;
173 		param.cache_size = 40;
174 		param.C = 1;
175 		param.eps = 1e-3;
176 		param.p = 0.1;
177 		param.shrinking = 1;
178 		param.probability = 0;
179 		param.nr_weight = 0;
180 		param.weight_label = new int[0];
181 		param.weight = new double[0];
182 
183 		// parse options
184 		StringTokenizer st = new StringTokenizer(args);
185 		String[] argv = new String[st.countTokens()];
186 		for(int i=0;i<argv.length;i++)
187 			argv[i] = st.nextToken();
188 
189 		for(int i=0;i<argv.length;i++)
190 		{
191 			if(argv[i].charAt(0) != '-') break;
192 			if(++i>=argv.length)
193 			{
194 				System.err.print("unknown option\n");
195 				break;
196 			}
197 			switch(argv[i-1].charAt(1))
198 			{
199 				case 's':
200 					param.svm_type = atoi(argv[i]);
201 					break;
202 				case 't':
203 					param.kernel_type = atoi(argv[i]);
204 					break;
205 				case 'd':
206 					param.degree = atoi(argv[i]);
207 					break;
208 				case 'g':
209 					param.gamma = atof(argv[i]);
210 					break;
211 				case 'r':
212 					param.coef0 = atof(argv[i]);
213 					break;
214 				case 'n':
215 					param.nu = atof(argv[i]);
216 					break;
217 				case 'm':
218 					param.cache_size = atof(argv[i]);
219 					break;
220 				case 'c':
221 					param.C = atof(argv[i]);
222 					break;
223 				case 'e':
224 					param.eps = atof(argv[i]);
225 					break;
226 				case 'p':
227 					param.p = atof(argv[i]);
228 					break;
229 				case 'h':
230 					param.shrinking = atoi(argv[i]);
231 					break;
232 				case 'b':
233 					param.probability = atoi(argv[i]);
234 					break;
235 				case 'w':
236 					++param.nr_weight;
237 					{
238 						int[] old = param.weight_label;
239 						param.weight_label = new int[param.nr_weight];
240 						System.arraycopy(old,0,param.weight_label,0,param.nr_weight-1);
241 					}
242 
243 					{
244 						double[] old = param.weight;
245 						param.weight = new double[param.nr_weight];
246 						System.arraycopy(old,0,param.weight,0,param.nr_weight-1);
247 					}
248 
249 					param.weight_label[param.nr_weight-1] = atoi(argv[i-1].substring(2));
250 					param.weight[param.nr_weight-1] = atof(argv[i]);
251 					break;
252 				default:
253 					System.err.print("unknown option\n");
254 			}
255 		}
256 
257 		// build problem
258 		svm_problem prob = new svm_problem();
259 		prob.l = point_list.size();
260 		prob.y = new double[prob.l];
261 
262 		if(param.kernel_type == svm_parameter.PRECOMPUTED)
263 		{
264 		}
265 		else if(param.svm_type == svm_parameter.EPSILON_SVR ||
266 			param.svm_type == svm_parameter.NU_SVR)
267 		{
268 			if(param.gamma == 0) param.gamma = 1;
269 			prob.x = new svm_node[prob.l][1];
270 			for(int i=0;i<prob.l;i++)
271 			{
272 				point p = point_list.elementAt(i);
273 				prob.x[i][0] = new svm_node();
274 				prob.x[i][0].index = 1;
275 				prob.x[i][0].value = p.x;
276 				prob.y[i] = p.y;
277 			}
278 
279 			// build model & classify
280 			svm_model model = svm.svm_train(prob, param);
281 			svm_node[] x = new svm_node[1];
282 			x[0] = new svm_node();
283 			x[0].index = 1;
284 			int[] j = new int[XLEN];
285 
286 			Graphics window_gc = getGraphics();
287 			for (int i = 0; i < XLEN; i++)
288 			{
289 				x[0].value = (double) i / XLEN;
290 				j[i] = (int)(YLEN*svm.svm_predict(model, x));
291 			}
292 
293 			buffer_gc.setColor(colors[0]);
294 			buffer_gc.drawLine(0,0,0,YLEN-1);
295 			window_gc.setColor(colors[0]);
296 			window_gc.drawLine(0,0,0,YLEN-1);
297 
298 			int p = (int)(param.p * YLEN);
299 			for(int i=1;i<XLEN;i++)
300 			{
301 				buffer_gc.setColor(colors[0]);
302 				buffer_gc.drawLine(i,0,i,YLEN-1);
303 				window_gc.setColor(colors[0]);
304 				window_gc.drawLine(i,0,i,YLEN-1);
305 
306 				buffer_gc.setColor(colors[5]);
307 				window_gc.setColor(colors[5]);
308 				buffer_gc.drawLine(i-1,j[i-1],i,j[i]);
309 				window_gc.drawLine(i-1,j[i-1],i,j[i]);
310 
311 				if(param.svm_type == svm_parameter.EPSILON_SVR)
312 				{
313 					buffer_gc.setColor(colors[2]);
314 					window_gc.setColor(colors[2]);
315 					buffer_gc.drawLine(i-1,j[i-1]+p,i,j[i]+p);
316 					window_gc.drawLine(i-1,j[i-1]+p,i,j[i]+p);
317 
318 					buffer_gc.setColor(colors[2]);
319 					window_gc.setColor(colors[2]);
320 					buffer_gc.drawLine(i-1,j[i-1]-p,i,j[i]-p);
321 					window_gc.drawLine(i-1,j[i-1]-p,i,j[i]-p);
322 				}
323 			}
324 		}
325 		else
326 		{
327 			if(param.gamma == 0) param.gamma = 0.5;
328 			prob.x = new svm_node [prob.l][2];
329 			for(int i=0;i<prob.l;i++)
330 			{
331 				point p = point_list.elementAt(i);
332 				prob.x[i][0] = new svm_node();
333 				prob.x[i][0].index = 1;
334 				prob.x[i][0].value = p.x;
335 				prob.x[i][1] = new svm_node();
336 				prob.x[i][1].index = 2;
337 				prob.x[i][1].value = p.y;
338 				prob.y[i] = p.value;
339 			}
340 
341 			// build model & classify
342 			svm_model model = svm.svm_train(prob, param);
343 			svm_node[] x = new svm_node[2];
344 			x[0] = new svm_node();
345 			x[1] = new svm_node();
346 			x[0].index = 1;
347 			x[1].index = 2;
348 
349 			Graphics window_gc = getGraphics();
350 			for (int i = 0; i < XLEN; i++)
351 				for (int j = 0; j < YLEN ; j++) {
352 					x[0].value = (double) i / XLEN;
353 					x[1].value = (double) j / YLEN;
354 					double d = svm.svm_predict(model, x);
355 					if (param.svm_type == svm_parameter.ONE_CLASS && d<0) d=2;
356 					buffer_gc.setColor(colors[(int)d]);
357 					window_gc.setColor(colors[(int)d]);
358 					buffer_gc.drawLine(i,j,i,j);
359 					window_gc.drawLine(i,j,i,j);
360 			}
361 		}
362 
363 		draw_all_points();
364 	}
365 
button_clear_clicked()366 	void button_clear_clicked()
367 	{
368 		clear_all();
369 	}
370 
button_save_clicked(String args)371 	void button_save_clicked(String args)
372 	{
373 		FileDialog dialog = new FileDialog(new Frame(),"Save",FileDialog.SAVE);
374 		dialog.setVisible(true);
375 		String filename = dialog.getDirectory() + dialog.getFile();
376 		if (filename == null) return;
377 		try {
378 			DataOutputStream fp = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(filename)));
379 
380 			int svm_type = svm_parameter.C_SVC;
381 			int svm_type_idx = args.indexOf("-s ");
382 			if(svm_type_idx != -1)
383 			{
384 				StringTokenizer svm_str_st = new StringTokenizer(args.substring(svm_type_idx+2).trim());
385 				svm_type = atoi(svm_str_st.nextToken());
386 			}
387 
388 			int n = point_list.size();
389 			if(svm_type == svm_parameter.EPSILON_SVR || svm_type == svm_parameter.NU_SVR)
390 			{
391 				for(int i=0;i<n;i++)
392 				{
393 					point p = point_list.elementAt(i);
394 					fp.writeBytes(p.y+" 1:"+p.x+"\n");
395 				}
396 			}
397 			else
398 			{
399 				for(int i=0;i<n;i++)
400 				{
401 					point p = point_list.elementAt(i);
402 					fp.writeBytes(p.value+" 1:"+p.x+" 2:"+p.y+"\n");
403 				}
404 			}
405 			fp.close();
406 		} catch (IOException e) { System.err.print(e); }
407 	}
408 
button_load_clicked()409 	void button_load_clicked()
410 	{
411 		FileDialog dialog = new FileDialog(new Frame(),"Load",FileDialog.LOAD);
412 		dialog.setVisible(true);
413 		String filename = dialog.getDirectory() + dialog.getFile();
414 		if (filename == null) return;
415 		clear_all();
416 		try {
417 			BufferedReader fp = new BufferedReader(new FileReader(filename));
418 			String line;
419 			while((line = fp.readLine()) != null)
420 			{
421 				StringTokenizer st = new StringTokenizer(line," \t\n\r\f:");
422 				if(st.countTokens() == 5)
423 				{
424 					byte value = (byte)atoi(st.nextToken());
425 					st.nextToken();
426 					double x = atof(st.nextToken());
427 					st.nextToken();
428 					double y = atof(st.nextToken());
429 					point_list.addElement(new point(x,y,value));
430 				}
431 				else if(st.countTokens() == 3)
432 				{
433 					double y = atof(st.nextToken());
434 					st.nextToken();
435 					double x = atof(st.nextToken());
436 					point_list.addElement(new point(x,y,current_value));
437 				}else
438 					break;
439 			}
440 			fp.close();
441 		} catch (IOException e) { System.err.print(e); }
442 		draw_all_points();
443 	}
444 
processMouseEvent(MouseEvent e)445 	protected void processMouseEvent(MouseEvent e)
446 	{
447 		if(e.getID() == MouseEvent.MOUSE_PRESSED)
448 		{
449 			if(e.getX() >= XLEN || e.getY() >= YLEN) return;
450 			point p = new point((double)e.getX()/XLEN,
451 					    (double)e.getY()/YLEN,
452 					    current_value);
453 			point_list.addElement(p);
454 			draw_point(p);
455 		}
456 	}
457 
paint(Graphics g)458 	public void paint(Graphics g)
459 	{
460 		// create buffer first time
461 		if(buffer == null) {
462 			buffer = this.createImage(XLEN,YLEN);
463 			buffer_gc = buffer.getGraphics();
464 			buffer_gc.setColor(colors[0]);
465 			buffer_gc.fillRect(0,0,XLEN,YLEN);
466 		}
467 		g.drawImage(buffer,0,0,this);
468 	}
469 
getPreferredSize()470 	public Dimension getPreferredSize() { return new Dimension(XLEN,YLEN+50); }
471 
setSize(Dimension d)472 	public void setSize(Dimension d) { setSize(d.width,d.height); }
setSize(int w,int h)473 	public void setSize(int w,int h) {
474 		super.setSize(w,h);
475 		XLEN = w;
476 		YLEN = h-50;
477 		clear_all();
478 	}
479 
main(String[] argv)480 	public static void main(String[] argv)
481 	{
482 		new AppletFrame("svm_toy",new svm_toy(),500,500+50);
483 	}
484 }
485 
486 class AppletFrame extends Frame {
AppletFrame(String title, Applet applet, int width, int height)487 	AppletFrame(String title, Applet applet, int width, int height)
488 	{
489 		super(title);
490 		this.addWindowListener(new WindowAdapter() {
491 			public void windowClosing(WindowEvent e) {
492 				System.exit(0);
493 			}
494 		});
495 		applet.init();
496 		applet.setSize(width,height);
497 		applet.start();
498 		this.add(applet);
499 		this.pack();
500 		this.setVisible(true);
501 	}
502 }
503