1 /*****************************************************************************
2 FILE : $Source: /projects/higgs1/SNNS/CVS/SNNS/xgui/sources/ui_inversion.c,v $
3 SHORTNAME : inversion.c
4 SNNS VERSION : 4.2
5
6 PURPOSE : contains all routines for handling inversion of NN, invented
7 by Alexander Linden
8
9 FUNCTIONS: -- ui_inversion
10 Purpose : Main program for the inversion
11 Calls : void ui_confirmOk();
12 Widget ui_xCreateButtonItem();
13 int ui_set_IO_units();
14 various X routines for widget handling
15
16 -- ui_invSetup
17 Purpose : Display setup panel for Inversion
18 Calls : Widget ui_xCreateDialogItem();
19 Widget ui_xCreateLabelItem();
20
21 -- ui_inv_popupDone
22 Purpose : read new params and close popup display
23 Calls : nothing
24
25 -- ui_invHelp
26 Purpose : display help information for inversion
27 Calls : nothing
28
29 -- ui_inv_helpDone
30 Purpose : close help window
31 Calls : nothing
32
33 -- ui_set_IO_units
34 Purpose : create a chain of input units
35 Calls : int krui_getUnitTType();
36 void krui_getUnitPosition();
37
38 -- ui_closeDisplay
39 Purpose : closing all widgets for inversion
40 Calls : nothing
41
42 -- ui_invNew
43 Purpose : restart the inversion
44 Calls : void ui_drawInput();
45
46 -- ui_invEvent
47 Purpose : event handler for graphic window
48 Calls : void ui_drawInput();
49
50 -- ui_inversionFromUpdate
51 Purpose : refresh the screen
52 Calls : void ui_drawInput();
53
54 -- ui_drawInput
55 Purpose : drawing the input units
56 Calls : int krui_getFirstUnit();
57 void ui_col_setPalette();
58 void krui_getUnitPosition();
59 void ui_drawGrowingThing();
60 position ui_utilPixUpperLeft();
61 position ui_utilPixLowerRight();
62 void ui_xDeleteRect();
63
64 -- ui_start_inversion
65 Purpose : Program to start inversion
66 Calls : X routines
67
68 -- ui_stop_inversion
69 Purpose : Program to stop inversion
70 Calls : X routines
71
72 -- ui_do_inversion
73 Purpose : Program for actual inversion algorithm
74 Calls : void ui_confirmOk();
75 void ui_sel_lookForItem();
76 int krui_initInversion();
77 void krui_inv_forwardPass();
78 int krui_inv_backwardPass();
79 void ui_drawInput();
80
81 AUTHOR : Guenter Mamier
82 DATE : 28.02.92
83 VERSION : 0.20
84
85 CHANGED BY : Sven Doering
86 RCS VERSION : $Revision: 2.11 $
87 LAST CHANGE : $Date: 1998/03/03 14:10:30 $
88
89 Copyright (c) 1990-1995 SNNS Group, IPVR, Univ. Stuttgart, FRG
90 Copyright (c) 1996-1998 SNNS Group, WSI, Univ. Tuebingen, FRG
91
92 ******************************************************************************/
93 #include <config.h>
94
95 #ifndef MASPAR_KERNEL
96
97 #include <stdio.h> /* For the Syntax message */
98 #include <stdlib.h>
99 #include <math.h>
100
101 #include "ui.h"
102
103 #include <X11/Shell.h>
104 #include <X11/Xaw3d/Form.h>
105 #include <X11/Xaw3d/Box.h>
106
107 #include "ui_xWidgets.h"
108 #include "ui_main.h"
109 #include "ui_mainP.h"
110 #include "ui_netGraph.h"
111 #include "ui_utilP.h"
112 #include "ui_display.h"
113 #include "ui_selection.h"
114 #include "ui_color.h"
115 #include "ui_confirmer.h"
116 #include "ui_xGraphic.h"
117 #include "ui_key.h"
118 #include "kr_ui.h"
119 #include "kr_typ.h"
120
121 #include "ui_inversion.ph"
122
123
124 /*****************************************************************************
125 FUNCTION : ui_inversion
126
127 PURPOSE : Main program for the inversion
128 NOTES : callback from the info panel
129 RETURNS :
130 UPDATE : 29.01.92
131 ******************************************************************************/
132
ui_inversion(Widget button,caddr_t call_data)133 void ui_inversion(Widget button, caddr_t call_data)
134 {
135
136 Widget fbutton,sbutton,stbutton,setbutton,stopbutton,helpbutton;
137 Arg args[10];
138 Cardinal n;
139 char buf[40];
140 struct UnitList *IUnit, *OUnit;
141 struct Ui_DisplayType *dPtr;
142 int maxx,maxy;
143 int test;
144
145 if (krui_getNoOfUnits() == 0){
146 ui_confirmOk("No network loaded !");
147 return;
148 }
149
150
151 if(INVERS_CREATED){
152 XRaiseWindow(XtDisplay(ui_InvRootWidget), XtWindow(ui_InvRootWidget));
153 return;
154 }
155
156 if((test = ui_set_IO_units()) == 1){
157 ui_confirmOk("No input and/or output units defined !");
158 return;
159 }
160
161
162 if ((displayPtr = ui_displ_getFreeItem()) == NULL) {
163 ui_confirmOk("No more memory for displays available!");
164 return;
165 }
166
167
168 /* now create the widget structure to display input units */
169
170 n = 0;
171 displayPtr->gridSize = 37;
172 dPtr = ui_displ_listPtr;
173 while(dPtr != NULL){
174 displayPtr->gridSize = dPtr->gridSize;
175 dPtr = dPtr->nextPtr;
176 }
177
178 sprintf(buf,"SNNS Inversion Display");
179 ui_InvRootWidget =
180 XtCreatePopupShell(buf, topLevelShellWidgetClass, ui_toplevel,args, n);
181 displayPtr->frameWidget =
182 XtCreateManagedWidget("form", formWidgetClass, ui_InvRootWidget,NULL,0);
183
184 fbutton = ui_xCreateButtonItem("done", displayPtr->frameWidget, NULL, NULL);
185 sbutton = ui_xCreateButtonItem("multiStep", displayPtr->frameWidget,
186 fbutton, NULL);
187 stopbutton = ui_xCreateButtonItem("stop", displayPtr->frameWidget,
188 sbutton, NULL);
189 stbutton = ui_xCreateButtonItem("new", displayPtr->frameWidget,
190 stopbutton, NULL);
191 setbutton = ui_xCreateButtonItem("setup", displayPtr->frameWidget,
192 stbutton, NULL);
193 helpbutton = ui_xCreateButtonItem("help", displayPtr->frameWidget,
194 setbutton, NULL);
195
196
197 /* get necessary window size */
198
199 maxy = maxx = 0;
200 IUnit = inputs;
201 do{
202 maxy = (IUnit->gridPos.y > maxy)? IUnit->gridPos.y: maxy;
203 maxx = (IUnit->gridPos.x > maxx)? IUnit->gridPos.x: maxx;
204 IUnit = IUnit->next;
205 }while(IUnit != NULL);
206 OUnit = outputs;
207 do{
208 maxy = (OUnit->gridPos.y > maxy)? OUnit->gridPos.y: maxy;
209 maxx = (OUnit->gridPos.x > maxx)? OUnit->gridPos.x: maxx;
210 OUnit = OUnit->next;
211 }while(OUnit != NULL);
212
213 n = 0;
214 /* XtSetArg(args[n], XtNwidth, displayPtr->width); n++; */
215 /* XtSetArg(args[n], XtNheight, displayPtr->height); n++; */
216 XtSetArg(args[n], XtNwidth, ++maxx * displayPtr->gridSize); n++;
217 XtSetArg(args[n], XtNheight, ++maxy * displayPtr->gridSize); n++;
218 XtSetArg(args[n], XtNfromVert, fbutton); n++;
219 XtSetArg(args[n], XtNleft, XtChainLeft); n++;
220 XtSetArg(args[n], XtNright, XtChainRight); n++;
221 XtSetArg(args[n], XtNtop, XtChainTop ); n++;
222 XtSetArg(args[n], XtNbottom, XtChainBottom); n++;
223 displayPtr->widget =
224 XtCreateManagedWidget("display",boxWidgetClass,displayPtr->frameWidget,
225 args,n);
226
227
228 /* define necessary callbacks */
229
230 XtAddCallback(fbutton, XtNcallback,(XtCallbackProc)ui_closeDisplay,NULL);
231 XtAddCallback(sbutton, XtNcallback,(XtCallbackProc)ui_start_inversion,NULL);
232 XtAddCallback(stbutton, XtNcallback, (XtCallbackProc) ui_invNew, NULL);
233 XtAddCallback(stopbutton, XtNcallback,
234 (XtCallbackProc) ui_stop_inversion, NULL);
235 XtAddCallback(setbutton, XtNcallback, (XtCallbackProc) ui_invSetup, NULL);
236 XtAddCallback(helpbutton, XtNcallback, (XtCallbackProc) ui_invHelp,
237 (caddr_t) TRUE);
238 XtAddEventHandler(displayPtr->widget,StructureNotifyMask | ExposureMask,
239 FALSE, (XtEventHandler) ui_invEvent,inv_display);
240 XtAddEventHandler(displayPtr->widget,KeyPressMask,FALSE,
241 (XtEventHandler)ui_key_control,(Cardinal *) 0);
242 ui_checkWindowPosition(ui_InvRootWidget);
243 XtPopup(ui_InvRootWidget, XtGrabNone);
244
245 INVERS_CREATED = 1;
246 inv_display = XtDisplay(ui_InvRootWidget);
247 inv_screen = DefaultScreen(inv_display);
248 displayPtr->drawable = XtWindow(displayPtr->widget);
249 XSelectInput(inv_display, displayPtr->drawable, ExposureMask);
250
251
252 }
253
254
255
256
257 /*****************************************************************************
258 FUNCTION : ui_invSetup
259
260 PURPOSE : Display setup panel for Inversion
261 NOTES :
262 RETURNS :
263 UPDATE : 20.02.92
264 *****************************************************************************/
ui_invSetup(Widget button,caddr_t call_data)265 static void ui_invSetup(Widget button, caddr_t call_data)
266 {
267 Widget ui_invBox,doneButton,helpButton;
268 Widget eta_lab,delta_lab,pat_lab,rat_lab;
269 Arg args[5];
270 Position x, y;
271 Dimension width, height;
272 Cardinal n;
273 char buf[40];
274
275
276 /* set Popup arguments */
277
278 n = 0;
279 XtSetArg(args[0], XtNwidth, &width);n++;
280 XtSetArg(args[1], XtNheight, &height);n++;
281 XtGetValues(button, args, n);
282 XtTranslateCoords(button, (Position)(width/2), (Position)(height/2), &x,&y);
283 n = 0;
284 XtSetArg(args[n], XtNx, x);n++;
285 XtSetArg(args[n], XtNy, y);n++;
286
287
288 /* Now create Popup */
289
290 ui_invpop = XtCreatePopupShell("setup", transientShellWidgetClass,
291 ui_toplevel, args, n);
292 ui_invBox = XtCreateManagedWidget("form", formWidgetClass, ui_invpop,
293 NULL, 0);
294 doneButton = ui_xCreateButtonItem("done", ui_invBox, NULL, NULL);
295 XtAddCallback(doneButton, XtNcallback, (XtCallbackProc) ui_inv_popupDone,
296 NULL);
297 helpButton = ui_xCreateButtonItem("help", ui_invBox, doneButton, NULL);
298 XtAddCallback(helpButton, XtNcallback, (XtCallbackProc) ui_invHelp, FALSE);
299 eta_lab = ui_xCreateLabelItem("eta =", ui_invBox,120,
300 NULL,doneButton);
301 sprintf(buf,"%g",INV_eta);
302 etaW = ui_xCreateDialogItem("eta_val",ui_invBox,buf,56,eta_lab,doneButton);
303 delta_lab = ui_xCreateLabelItem("delta_max =",ui_invBox,120,
304 NULL,eta_lab);
305 sprintf(buf,"%g",INV_delta_max);
306 delta_maxW = ui_xCreateDialogItem("delta_max_val",ui_invBox,
307 buf, 56, delta_lab, etaW);
308 pat_lab = ui_xCreateLabelItem("Input pattern =",ui_invBox,120,NULL,
309 delta_lab);
310 sprintf(buf,"%g",INPUT_PAT);
311 inPatW = ui_xCreateDialogItem("input_pat_val",ui_invBox,buf,56,
312 pat_lab,delta_maxW);
313 rat_lab = ui_xCreateLabelItem("2nd approx ratio",ui_invBox,120,NULL,
314 pat_lab);
315 sprintf(buf,"%g",RATIO);
316 ratioW = ui_xCreateDialogItem("ratio_val",ui_invBox,buf,56,
317 rat_lab,inPatW);
318
319
320 /* Display popup now */
321
322 ui_checkWindowPosition(ui_invpop);
323 XtPopup(ui_invpop, XtGrabExclusive);
324 ui_xDontResizeWidget(ui_invpop);
325 }
326
327
328
329
330
331 /*****************************************************************************
332 FUNCTION : ui_inv_popupDone
333
334 PURPOSE : read new params and close popup display
335 NOTES :
336 RETURNS :
337 UPDATE : 20.02.92
338 *****************************************************************************/
ui_inv_popupDone(Widget button,caddr_t call_data)339 static void ui_inv_popupDone(Widget button, caddr_t call_data)
340 {
341 struct UnitList *IUnit;
342
343 INPUT_PAT = (float)ui_xFloatFromAsciiWidget(inPatW);
344 INPUT_PAT = (INPUT_PAT > 1.0)? 1.0 :INPUT_PAT;
345 INPUT_PAT = (INPUT_PAT < 0.0)? 0.0 :INPUT_PAT;
346 INV_eta = (float)ui_xFloatFromAsciiWidget(etaW);
347 INV_delta_max = (float)ui_xFloatFromAsciiWidget(delta_maxW);
348 RATIO = (float)ui_xFloatFromAsciiWidget(ratioW);
349 XtDestroyWidget(ui_invpop);
350
351 IUnit = inputs;
352 while(IUnit != NULL){
353 IUnit->act = (FlintType)INPUT_PAT;
354 IUnit->i_act = (FlintType)INPUT_PAT;
355 if(INPUT_PAT == 1.0)
356 IUnit->im_act = 9.2102404;
357 else if(INPUT_PAT == 0.0)
358 IUnit->im_act = -9.2102404;
359 else
360 IUnit->im_act = (FlintType)(-log((double)(1.0/INPUT_PAT - 1.0)));
361 IUnit = IUnit->next;
362 }
363 ui_drawInput();
364 }
365
366
367
368
369
370 /*****************************************************************************
371 FUNCTION : ui_inv_helpDone
372
373 PURPOSE : destroy help window
374 NOTES :
375 RETURNS :
376 UPDATE : 03.03.92
377 *****************************************************************************/
ui_inv_helpDone(Widget button,caddr_t call_data)378 static void ui_inv_helpDone(Widget button, caddr_t call_data)
379 {
380 XtDestroyWidget(XtParent(XtParent(button)));
381 }
382
383
384
385
386 /*****************************************************************************
387 FUNCTION : ui_invHelp
388
389 PURPOSE : display help information for inversion
390 NOTES :
391 RETURNS :
392 UPDATE : 03.03.92
393 *****************************************************************************/
ui_invHelp(Widget button,Boolean fromMain,caddr_t call_data)394 static void ui_invHelp(Widget button, Boolean fromMain, caddr_t call_data)
395 {
396 Widget ui_invHBox,ui_invHelp,doneButton,lab[10];
397 Arg args[5];
398 Position x, y;
399 Dimension width, height;
400 Cardinal n;
401 char buf[80];
402
403 /* set Popup arguments */
404
405 n = 0;
406 XtSetArg(args[0], XtNwidth, &width);n++;
407 XtSetArg(args[1], XtNheight, &height);n++;
408 XtGetValues(button, args, n);
409 XtTranslateCoords(button, (Position)(width), (Position)(height), &x, &y);
410 n = 0;
411 XtSetArg(args[n], XtNx, x);n++;
412 XtSetArg(args[n], XtNy, y+100);n++;
413
414
415 /* Now create Popup */
416
417 ui_invHelp = XtCreatePopupShell("help", transientShellWidgetClass,
418 ui_toplevel, args, n);
419 ui_invHBox = XtCreateManagedWidget("form", formWidgetClass, ui_invHelp,
420 NULL, 0);
421 doneButton = ui_xCreateButtonItem("done", ui_invHBox, NULL, NULL);
422 XtAddCallback(doneButton, XtNcallback, (XtCallbackProc) ui_inv_helpDone, NULL);
423
424
425 if(fromMain){
426 sprintf(buf,"Start/continue inversion with 'STEP'");
427 lab[0] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,doneButton);
428 sprintf(buf,"Halt inversion run anytime with 'STOP'");
429 lab[1] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[0]);
430 sprintf(buf,"Reset inversion with 'NEW'");
431 lab[2] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[1]);
432 sprintf(buf,"Change parameters with 'SETUP'");
433 lab[3] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[2]);
434 sprintf(buf,"After SETUP continue with 'STEP',");
435 lab[4] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[3]);
436 sprintf(buf," or restart with 'NEW','STEP'");
437 lab[5] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[4]);
438 sprintf(buf,"HINT: If inversion is performed on an untrained net,");
439 lab[6] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[5]);
440 sprintf(buf," or on a trained net with an average error of more than 0.05,");
441 lab[7] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[6]);
442 sprintf(buf," the algorithm is very likely not to converge !!");
443 lab[8] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[7]);
444 }else{
445 sprintf(buf,"eta : The learn parameter; should range from 1.0 to 10.0");
446 lab[0] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,doneButton);
447 sprintf(buf,"delta_max : The maximum allowed error for a output unit");
448 lab[1] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[0]);
449 sprintf(buf,"Input pattern: The initial activation for all input units");
450 lab[2] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[1]);
451 sprintf(buf,"2nd approx : The degree to which the target input pattern");
452 lab[3] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[2]);
453 sprintf(buf," is dependent of the initial input pattern");
454 lab[4] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[3]);
455 sprintf(buf," good values range from 0.2 to 0.8");
456 lab[5] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[4]);
457 }
458
459
460 /* Display popup now */
461
462 ui_checkWindowPosition(ui_invHelp);
463 XtPopup(ui_invHelp, XtGrabExclusive);
464 XFlush(ui_display);
465
466
467 }
468
469
470
471
472 /*****************************************************************************
473 FUNCTION : ui_set_IO_units
474
475 PURPOSE : create a chain of input units and the corresponding pattern
476 NOTES :
477 RETURNS :
478 UPDATE : 29.01.92
479 *****************************************************************************/
ui_set_IO_units(void)480 static int ui_set_IO_units(void)
481 {
482 int next;
483 int u_type;
484 struct PosType position;
485 struct UnitList *IUnit,*OUnit,*dummy1,*dummy2;
486 int i_count = 0,
487 o_count = 0,
488 i,
489 max_no;
490
491 if((next = krui_getFirstUnit()) == 0)return(0);
492
493 IUnit = (struct UnitList *) malloc(sizeof(struct UnitList));
494 inputs = IUnit;
495 IUnit->prev = NULL;
496 OUnit = (struct UnitList *) malloc(sizeof(struct UnitList));
497 outputs = OUnit;
498 IUnit->prev = NULL;
499 max_no = krui_getNoOfUnits();
500 for(i=1; i<= max_no; i++){
501 u_type = krui_getUnitTType(next);
502 if(u_type == INPUT){
503 i_count++;
504 krui_getUnitPosition(next,&position);
505 dummy1 = IUnit;
506 IUnit->no = next;
507 IUnit->gridPos = position;
508 IUnit->act = (FlintType)INPUT_PAT;
509 IUnit->i_act = (FlintType)INPUT_PAT;
510 if(INPUT_PAT == 1.0)
511 IUnit->im_act = 9.2102404; /* = -ln(1/0.9999 - 1); */
512 else if(INPUT_PAT == 0.0)
513 IUnit->im_act = -9.2102404; /* = -ln(1/0.0001 - 1); */
514 else
515 IUnit->im_act =(FlintType)( -log((double)(1.0/INPUT_PAT - 1.0)));
516 IUnit->next = (struct UnitList *) malloc(sizeof(struct UnitList));
517 IUnit = IUnit->next;
518 IUnit->prev = dummy1;
519 }else if(u_type == OUTPUT){
520 o_count++;
521 krui_getUnitPosition(next,&position);
522 dummy2 = OUnit;
523 OUnit->no = next;
524 OUnit->gridPos = position;
525 OUnit->act = 0.0;
526 OUnit->next = (struct UnitList *) malloc(sizeof(struct UnitList));
527 OUnit = OUnit->next;
528 OUnit->prev = dummy2;
529 }
530 next=krui_getNextUnit();
531 }
532
533 if(i_count == 0 || o_count == 0){
534
535 /* Stop inversion if no input or output units are defined */
536 return(1);
537 }else{
538
539 /* Finish the pointer chain */
540 dummy1->next = NULL;
541 dummy2->next = NULL;
542 return(0);
543 }
544
545 }
546
547
548
549
550 /*****************************************************************************
551 FUNCTION : ui_closeDisplay
552
553 PURPOSE : closing all widgets for inversion
554 NOTES :
555 RETURNS :
556 UPDATE : 29.01.92
557 *****************************************************************************/
ui_closeDisplay(Widget w,caddr_t call_data)558 static void ui_closeDisplay(Widget w, caddr_t call_data)
559 {
560
561
562 if(INV_RUNNING){
563 ui_confirmOk("Stop inversion run before quiting !");
564 return;
565 }
566 XtDestroyWidget(ui_InvRootWidget);
567 INVERS_CREATED = 0;
568 inputs = NULL;
569 outputs = NULL;
570 }
571
572
573 /*****************************************************************************
574 FUNCTION : ui_invNew
575
576 PURPOSE : restart the inversion
577 NOTES :
578 RETURNS :
579 UPDATE : 11.02.92
580 *****************************************************************************/
ui_invNew(Widget w,caddr_t call_data)581 static void ui_invNew(Widget w, caddr_t call_data)
582 {
583 struct UnitList *IUnit, *OUnit;
584
585 IUnit = inputs;
586 while(IUnit != NULL){
587 IUnit->act = (FlintType)INPUT_PAT;
588 IUnit->i_act = (FlintType)INPUT_PAT;
589 if(INPUT_PAT == 1.0)
590 IUnit->im_act = 9.2102404; /* = -ln(1/0.9999 - 1); */
591 else if(INPUT_PAT == 0.0)
592 IUnit->im_act = -9.2102404; /* = -ln(1/0.0001 - 1); */
593 else
594 IUnit->im_act = (FlintType)(-log((double)(1.0/INPUT_PAT - 1.0)));
595 IUnit = IUnit->next;
596 }
597 OUnit = outputs;
598 while(OUnit != NULL){
599 OUnit->act = 0.0;
600 OUnit->i_act = 0.0;
601 OUnit = OUnit->next;
602 }
603 ui_drawInput();
604 INV_NEW = 1;
605 }
606
607
608
609
610 /*****************************************************************************
611 FUNCTION : ui_invEvent
612
613 PURPOSE : event handler for graphic window
614 NOTES :
615 RETURNS :
616 UPDATE : 20.02.92
617 *****************************************************************************/
ui_invEvent(Widget w,Display * display,XEvent * event)618 static void ui_invEvent(Widget w, Display *display, XEvent *event)
619 {
620 switch (event->type){
621 case Expose:
622 if (event->xexpose.count == 0)
623 ui_drawInput();
624 break;
625 default:
626 break;
627 }
628 }
629
630
631
632
633
634 /*****************************************************************************
635 FUNCTION : ui_drawInput
636
637 PURPOSE : drawing the input units
638 NOTES :
639 RETURNS :
640 UPDATE : 29.01.92
641 *****************************************************************************/
ui_drawInput(void)642 static void ui_drawInput(void)
643 {
644
645 int next;
646 int u_type;
647 int dx,dy;
648 int procent_value;
649 struct PosType position,pixpos,pixpos2;
650 struct UnitList *IUnit, *OUnit;
651
652
653
654 /* do nothing if no net is loaded */
655
656 if((next = krui_getFirstUnit()) == 0)return;
657
658
659 /* prepare window for drawing */
660
661 displayPtr->frozen = FALSE;
662 XClearWindow(inv_display,displayPtr->drawable);
663 if(ui_col_monochromeMode){
664 XSetBackground(inv_display,ui_gc,
665 ui_backgroundColor);
666 XSetForeground(inv_display,
667 ui_gc,ui_textColor);
668
669 /* draw rectangle for EACH input/output unit */
670 do{
671 u_type = krui_getUnitTType(next);
672 if(u_type == OUTPUT || u_type == INPUT){
673 krui_getUnitPosition(next,&position);
674 ui_drawGrowingThing(displayPtr, position, -100);
675 }
676 }while((next=krui_getNextUnit()) != 0);
677 }else{
678 XSetBackground(inv_display,ui_gc,
679 ui_backgroundColor);
680 XSetForeground(inv_display,
681 ui_gc, ui_editColor[UI_BLACK]);
682 XSetFunction(inv_display, ui_gc, GXcopy);
683 }
684
685
686 /* draw activation of input units */
687
688 IUnit = inputs;
689 do{
690 position.x = displayPtr->gridSize * (IUnit->gridPos.x-displayPtr->origin.x) +
691 displayPtr->gridSize/2;
692 position.y = displayPtr->gridSize * (IUnit->gridPos.y-displayPtr->origin.y) +
693 displayPtr->gridSize/2;
694 procent_value = (int)(100.0*IUnit->act);
695 if(ui_col_monochromeMode){
696 pixpos = ui_utilPixUpperLeft(displayPtr,IUnit->gridPos);
697 pixpos2 = ui_utilPixLowerRight(displayPtr,IUnit->gridPos,0);
698 dx = dy = (int)((float)(pixpos2.x - pixpos.x)*IUnit->act);
699 pixpos.x += (int)((float)(pixpos2.x-pixpos.x)*0.5*(1.0 - IUnit->act)+0.5);
700 pixpos.y += (int)((float)(pixpos2.y-pixpos.y)*0.5*(1.0 - IUnit->act)+0.5);
701 XFillRectangle(inv_display, displayPtr->drawable, ui_gc,
702 pixpos.x,pixpos.y,(unsigned int) dx,(unsigned int) dy);
703 }else{
704 pixpos = ui_utilPixUpperLeft(displayPtr,IUnit->gridPos);
705 pixpos2 = ui_utilPixLowerRight(displayPtr,IUnit->gridPos,0);
706 XSetForeground(inv_display, ui_gc,
707 ui_col_rangePixels[ui_col_steps+procent_value*ui_col_steps DIV 100]);
708 ui_xDeleteRect(inv_display, displayPtr->drawable, ui_gc,pixpos,pixpos2);
709 }
710 IUnit = IUnit->next;
711 }while(IUnit != NULL);
712
713
714 /* draw activation of output units */
715
716 OUnit = outputs;
717 do{
718 position.x = displayPtr->gridSize * (OUnit->gridPos.x-displayPtr->origin.x) +
719 displayPtr->gridSize/2;
720 position.y = displayPtr->gridSize * (OUnit->gridPos.y-displayPtr->origin.y) +
721 displayPtr->gridSize/2;
722
723 procent_value = (int)(100.0*OUnit->act);
724 if(NOT ui_col_monochromeMode){
725 pixpos = ui_utilPixUpperLeft(displayPtr,OUnit->gridPos);
726 pixpos2 = ui_utilPixLowerRight(displayPtr,OUnit->gridPos,0);
727 XSetForeground(inv_display, ui_gc,
728 ui_col_rangePixels[ui_col_steps+procent_value*ui_col_steps DIV 100]);
729 ui_xDeleteRect(inv_display, displayPtr->drawable, ui_gc,pixpos,pixpos2);
730 }else{
731 pixpos = ui_utilPixUpperLeft(displayPtr,OUnit->gridPos);
732 pixpos2 = ui_utilPixLowerRight(displayPtr,OUnit->gridPos,0);
733 dx = dy = (int)((float)(pixpos2.x - pixpos.x)*OUnit->act);
734 pixpos.x += (int)((float)(pixpos2.x-pixpos.x)*0.5*(1.0 - OUnit->act)+0.5);
735 pixpos.y += (int)((float)(pixpos2.y-pixpos.y)*0.5*(1.0 - OUnit->act)+0.5);
736 XFillRectangle(inv_display, displayPtr->drawable, ui_gc,
737 pixpos.x,pixpos.y,(unsigned int) dx,(unsigned int) dy);
738 }
739 OUnit = OUnit->next;
740 }while(OUnit != NULL);
741
742
743
744 /* drawing finished */
745
746 XFlush(inv_display);
747 displayPtr->frozen = TRUE;
748 }
749
750
751
752
753
754 /*****************************************************************************
755 FUNCTION : ui_start_inversion
756
757 PURPOSE : Program to start inversion
758 NOTES : callback from the control panel
759 RETURNS :
760 UPDATE : 29.01.92
761 ******************************************************************************/
ui_start_inversion(Widget button,caddr_t call_data)762 static void ui_start_inversion(Widget button, caddr_t call_data)
763 {
764 if (ui_workProcId)
765 XtRemoveWorkProc(ui_workProcId); /* kill old workProc */
766 ui_workType = 99;
767 INV_RUNNING = 1;
768 ui_workProcId = XtAppAddWorkProc(ui_appContext, (XtWorkProc) ui_do_inversion,NULL);
769 }
770
771
772
773 /*****************************************************************************
774 FUNCTION : ui_stop_inversion
775
776 PURPOSE : Program to stop inversion
777 NOTES : callback from the control panel
778 RETURNS :
779 UPDATE : 29.01.92
780 ******************************************************************************/
ui_stop_inversion(Widget button,caddr_t call_data)781 static void ui_stop_inversion(Widget button, caddr_t call_data)
782 {
783 if(ui_workProcId){
784 INV_RUNNING = 0;
785 ui_drawInput();
786 printf("cycle %d inversion error %f, %d error units left\n",
787 INV_cycle,INV_error,INV_units);
788 XtRemoveWorkProc(ui_workProcId); /* kill old workProc */
789 ui_workProcId = (XtWorkProcId) NULL;
790 }
791 }
792
793
794
795 /*****************************************************************************
796 FUNCTION : ui_do_inversion
797
798 PURPOSE : Program for actual inversion algorithm
799 NOTES : callback from the control panel
800 RETURNS :
801 UPDATE : 29.01.92
802 ******************************************************************************/
803
ui_do_inversion(Widget button,caddr_t call_data)804 static Boolean ui_do_inversion(Widget button, caddr_t call_data)
805 {
806 struct UnitList *OUnit;
807 struct SelectionType *SelDummy;
808 int dummy;
809 double old_err;
810 int selUnits, err_units;
811 int err;
812 static int growing_errors = 0;
813
814
815 /* set output pattern */
816
817 if(INV_NEW){
818 INV_cycle = 0;
819 selUnits = 0;
820 if(krui_getNoOfPatterns() == 0){
821 ui_confirmOk("Please load patterns first !");
822 INV_RUNNING = 0;
823 return(TRUE);
824 }
825 OUnit = outputs;
826 while(OUnit != NULL){
827 if((SelDummy = ui_sel_lookForItem(OUnit->no)) != NULL){
828 OUnit->i_act = 1.0;
829 OUnit->act = 1.0;
830 selUnits++;
831 }else{
832 OUnit->i_act = 0.0;
833 OUnit->act = 0.0;
834 }
835 OUnit = OUnit->next;
836 }
837 if(!selUnits){
838 ui_confirmOk("No target output selected !!");
839 INV_RUNNING = 0;
840 return(TRUE);
841 }
842 INV_NEW = 0;
843 }
844
845
846 /* do the inversion */
847
848 if((err = krui_initInversion()) < 0){
849 printf("init returned error %d\n",err);
850 INV_RUNNING = 0;
851 return(TRUE);
852 }
853
854 INV_cycle++;
855 err_units = 0;
856 old_err = INV_error;
857 krui_inv_forwardPass(inputs);
858 INV_error = krui_inv_backwardPass(INV_eta,INV_delta_max,&err_units,RATIO,
859 inputs,outputs);
860 INV_units = err_units;
861 if((dummy=(INV_cycle%50)) == 0)
862 printf("cycle %d inversion error %f still %d error unit(s)\n",
863 INV_cycle,INV_error,INV_units);
864 if(old_err<= INV_error)growing_errors++;
865 else growing_errors = 0;
866 /*
867 if(growing_errors > 50){
868 growing_errors = 0;
869 ui_drawInput();
870 ui_confirmOk(" Inversion error does not diminish!\n Net might not be properly trained !");
871 INV_RUNNING = 0;
872 return(TRUE);
873 }
874 */
875
876 /* check the result of this inversion step */
877
878 if(INV_units > 0){
879
880 /* while still one unit has an error > delta_max return FALSE, */
881 /* to start another cycle */
882 return(FALSE);
883 }else{
884
885 /* algorithm has converged, display discovered activation pattern */
886 printf("cycle %d inversion error %f, %d error units left\n",
887 INV_cycle,INV_error,INV_units);
888 ui_drawInput();
889 INV_RUNNING = 0;
890 return(TRUE);
891 }
892
893
894 }
895
896 #endif
897
898
899