/***************************************************************************** FILE : $Source: /projects/higgs1/SNNS/CVS/SNNS/xgui/sources/ui_inversion.c,v $ SHORTNAME : inversion.c SNNS VERSION : 4.2 PURPOSE : contains all routines for handling inversion of NN, invented by Alexander Linden FUNCTIONS: -- ui_inversion Purpose : Main program for the inversion Calls : void ui_confirmOk(); Widget ui_xCreateButtonItem(); int ui_set_IO_units(); various X routines for widget handling -- ui_invSetup Purpose : Display setup panel for Inversion Calls : Widget ui_xCreateDialogItem(); Widget ui_xCreateLabelItem(); -- ui_inv_popupDone Purpose : read new params and close popup display Calls : nothing -- ui_invHelp Purpose : display help information for inversion Calls : nothing -- ui_inv_helpDone Purpose : close help window Calls : nothing -- ui_set_IO_units Purpose : create a chain of input units Calls : int krui_getUnitTType(); void krui_getUnitPosition(); -- ui_closeDisplay Purpose : closing all widgets for inversion Calls : nothing -- ui_invNew Purpose : restart the inversion Calls : void ui_drawInput(); -- ui_invEvent Purpose : event handler for graphic window Calls : void ui_drawInput(); -- ui_inversionFromUpdate Purpose : refresh the screen Calls : void ui_drawInput(); -- ui_drawInput Purpose : drawing the input units Calls : int krui_getFirstUnit(); void ui_col_setPalette(); void krui_getUnitPosition(); void ui_drawGrowingThing(); position ui_utilPixUpperLeft(); position ui_utilPixLowerRight(); void ui_xDeleteRect(); -- ui_start_inversion Purpose : Program to start inversion Calls : X routines -- ui_stop_inversion Purpose : Program to stop inversion Calls : X routines -- ui_do_inversion Purpose : Program for actual inversion algorithm Calls : void ui_confirmOk(); void ui_sel_lookForItem(); int krui_initInversion(); void krui_inv_forwardPass(); int krui_inv_backwardPass(); void ui_drawInput(); AUTHOR : Guenter Mamier DATE : 28.02.92 VERSION : 0.20 CHANGED BY : Sven Doering RCS VERSION : $Revision: 2.11 $ LAST CHANGE : $Date: 1998/03/03 14:10:30 $ Copyright (c) 1990-1995 SNNS Group, IPVR, Univ. Stuttgart, FRG Copyright (c) 1996-1998 SNNS Group, WSI, Univ. Tuebingen, FRG ******************************************************************************/ #include #ifndef MASPAR_KERNEL #include /* For the Syntax message */ #include #include #include "ui.h" #include #include #include #include "ui_xWidgets.h" #include "ui_main.h" #include "ui_mainP.h" #include "ui_netGraph.h" #include "ui_utilP.h" #include "ui_display.h" #include "ui_selection.h" #include "ui_color.h" #include "ui_confirmer.h" #include "ui_xGraphic.h" #include "ui_key.h" #include "kr_ui.h" #include "kr_typ.h" #include "ui_inversion.ph" /***************************************************************************** FUNCTION : ui_inversion PURPOSE : Main program for the inversion NOTES : callback from the info panel RETURNS : UPDATE : 29.01.92 ******************************************************************************/ void ui_inversion(Widget button, caddr_t call_data) { Widget fbutton,sbutton,stbutton,setbutton,stopbutton,helpbutton; Arg args[10]; Cardinal n; char buf[40]; struct UnitList *IUnit, *OUnit; struct Ui_DisplayType *dPtr; int maxx,maxy; int test; if (krui_getNoOfUnits() == 0){ ui_confirmOk("No network loaded !"); return; } if(INVERS_CREATED){ XRaiseWindow(XtDisplay(ui_InvRootWidget), XtWindow(ui_InvRootWidget)); return; } if((test = ui_set_IO_units()) == 1){ ui_confirmOk("No input and/or output units defined !"); return; } if ((displayPtr = ui_displ_getFreeItem()) == NULL) { ui_confirmOk("No more memory for displays available!"); return; } /* now create the widget structure to display input units */ n = 0; displayPtr->gridSize = 37; dPtr = ui_displ_listPtr; while(dPtr != NULL){ displayPtr->gridSize = dPtr->gridSize; dPtr = dPtr->nextPtr; } sprintf(buf,"SNNS Inversion Display"); ui_InvRootWidget = XtCreatePopupShell(buf, topLevelShellWidgetClass, ui_toplevel,args, n); displayPtr->frameWidget = XtCreateManagedWidget("form", formWidgetClass, ui_InvRootWidget,NULL,0); fbutton = ui_xCreateButtonItem("done", displayPtr->frameWidget, NULL, NULL); sbutton = ui_xCreateButtonItem("multiStep", displayPtr->frameWidget, fbutton, NULL); stopbutton = ui_xCreateButtonItem("stop", displayPtr->frameWidget, sbutton, NULL); stbutton = ui_xCreateButtonItem("new", displayPtr->frameWidget, stopbutton, NULL); setbutton = ui_xCreateButtonItem("setup", displayPtr->frameWidget, stbutton, NULL); helpbutton = ui_xCreateButtonItem("help", displayPtr->frameWidget, setbutton, NULL); /* get necessary window size */ maxy = maxx = 0; IUnit = inputs; do{ maxy = (IUnit->gridPos.y > maxy)? IUnit->gridPos.y: maxy; maxx = (IUnit->gridPos.x > maxx)? IUnit->gridPos.x: maxx; IUnit = IUnit->next; }while(IUnit != NULL); OUnit = outputs; do{ maxy = (OUnit->gridPos.y > maxy)? OUnit->gridPos.y: maxy; maxx = (OUnit->gridPos.x > maxx)? OUnit->gridPos.x: maxx; OUnit = OUnit->next; }while(OUnit != NULL); n = 0; /* XtSetArg(args[n], XtNwidth, displayPtr->width); n++; */ /* XtSetArg(args[n], XtNheight, displayPtr->height); n++; */ XtSetArg(args[n], XtNwidth, ++maxx * displayPtr->gridSize); n++; XtSetArg(args[n], XtNheight, ++maxy * displayPtr->gridSize); n++; XtSetArg(args[n], XtNfromVert, fbutton); n++; XtSetArg(args[n], XtNleft, XtChainLeft); n++; XtSetArg(args[n], XtNright, XtChainRight); n++; XtSetArg(args[n], XtNtop, XtChainTop ); n++; XtSetArg(args[n], XtNbottom, XtChainBottom); n++; displayPtr->widget = XtCreateManagedWidget("display",boxWidgetClass,displayPtr->frameWidget, args,n); /* define necessary callbacks */ XtAddCallback(fbutton, XtNcallback,(XtCallbackProc)ui_closeDisplay,NULL); XtAddCallback(sbutton, XtNcallback,(XtCallbackProc)ui_start_inversion,NULL); XtAddCallback(stbutton, XtNcallback, (XtCallbackProc) ui_invNew, NULL); XtAddCallback(stopbutton, XtNcallback, (XtCallbackProc) ui_stop_inversion, NULL); XtAddCallback(setbutton, XtNcallback, (XtCallbackProc) ui_invSetup, NULL); XtAddCallback(helpbutton, XtNcallback, (XtCallbackProc) ui_invHelp, (caddr_t) TRUE); XtAddEventHandler(displayPtr->widget,StructureNotifyMask | ExposureMask, FALSE, (XtEventHandler) ui_invEvent,inv_display); XtAddEventHandler(displayPtr->widget,KeyPressMask,FALSE, (XtEventHandler)ui_key_control,(Cardinal *) 0); ui_checkWindowPosition(ui_InvRootWidget); XtPopup(ui_InvRootWidget, XtGrabNone); INVERS_CREATED = 1; inv_display = XtDisplay(ui_InvRootWidget); inv_screen = DefaultScreen(inv_display); displayPtr->drawable = XtWindow(displayPtr->widget); XSelectInput(inv_display, displayPtr->drawable, ExposureMask); } /***************************************************************************** FUNCTION : ui_invSetup PURPOSE : Display setup panel for Inversion NOTES : RETURNS : UPDATE : 20.02.92 *****************************************************************************/ static void ui_invSetup(Widget button, caddr_t call_data) { Widget ui_invBox,doneButton,helpButton; Widget eta_lab,delta_lab,pat_lab,rat_lab; Arg args[5]; Position x, y; Dimension width, height; Cardinal n; char buf[40]; /* set Popup arguments */ n = 0; XtSetArg(args[0], XtNwidth, &width);n++; XtSetArg(args[1], XtNheight, &height);n++; XtGetValues(button, args, n); XtTranslateCoords(button, (Position)(width/2), (Position)(height/2), &x,&y); n = 0; XtSetArg(args[n], XtNx, x);n++; XtSetArg(args[n], XtNy, y);n++; /* Now create Popup */ ui_invpop = XtCreatePopupShell("setup", transientShellWidgetClass, ui_toplevel, args, n); ui_invBox = XtCreateManagedWidget("form", formWidgetClass, ui_invpop, NULL, 0); doneButton = ui_xCreateButtonItem("done", ui_invBox, NULL, NULL); XtAddCallback(doneButton, XtNcallback, (XtCallbackProc) ui_inv_popupDone, NULL); helpButton = ui_xCreateButtonItem("help", ui_invBox, doneButton, NULL); XtAddCallback(helpButton, XtNcallback, (XtCallbackProc) ui_invHelp, FALSE); eta_lab = ui_xCreateLabelItem("eta =", ui_invBox,120, NULL,doneButton); sprintf(buf,"%g",INV_eta); etaW = ui_xCreateDialogItem("eta_val",ui_invBox,buf,56,eta_lab,doneButton); delta_lab = ui_xCreateLabelItem("delta_max =",ui_invBox,120, NULL,eta_lab); sprintf(buf,"%g",INV_delta_max); delta_maxW = ui_xCreateDialogItem("delta_max_val",ui_invBox, buf, 56, delta_lab, etaW); pat_lab = ui_xCreateLabelItem("Input pattern =",ui_invBox,120,NULL, delta_lab); sprintf(buf,"%g",INPUT_PAT); inPatW = ui_xCreateDialogItem("input_pat_val",ui_invBox,buf,56, pat_lab,delta_maxW); rat_lab = ui_xCreateLabelItem("2nd approx ratio",ui_invBox,120,NULL, pat_lab); sprintf(buf,"%g",RATIO); ratioW = ui_xCreateDialogItem("ratio_val",ui_invBox,buf,56, rat_lab,inPatW); /* Display popup now */ ui_checkWindowPosition(ui_invpop); XtPopup(ui_invpop, XtGrabExclusive); ui_xDontResizeWidget(ui_invpop); } /***************************************************************************** FUNCTION : ui_inv_popupDone PURPOSE : read new params and close popup display NOTES : RETURNS : UPDATE : 20.02.92 *****************************************************************************/ static void ui_inv_popupDone(Widget button, caddr_t call_data) { struct UnitList *IUnit; INPUT_PAT = (float)ui_xFloatFromAsciiWidget(inPatW); INPUT_PAT = (INPUT_PAT > 1.0)? 1.0 :INPUT_PAT; INPUT_PAT = (INPUT_PAT < 0.0)? 0.0 :INPUT_PAT; INV_eta = (float)ui_xFloatFromAsciiWidget(etaW); INV_delta_max = (float)ui_xFloatFromAsciiWidget(delta_maxW); RATIO = (float)ui_xFloatFromAsciiWidget(ratioW); XtDestroyWidget(ui_invpop); IUnit = inputs; while(IUnit != NULL){ IUnit->act = (FlintType)INPUT_PAT; IUnit->i_act = (FlintType)INPUT_PAT; if(INPUT_PAT == 1.0) IUnit->im_act = 9.2102404; else if(INPUT_PAT == 0.0) IUnit->im_act = -9.2102404; else IUnit->im_act = (FlintType)(-log((double)(1.0/INPUT_PAT - 1.0))); IUnit = IUnit->next; } ui_drawInput(); } /***************************************************************************** FUNCTION : ui_inv_helpDone PURPOSE : destroy help window NOTES : RETURNS : UPDATE : 03.03.92 *****************************************************************************/ static void ui_inv_helpDone(Widget button, caddr_t call_data) { XtDestroyWidget(XtParent(XtParent(button))); } /***************************************************************************** FUNCTION : ui_invHelp PURPOSE : display help information for inversion NOTES : RETURNS : UPDATE : 03.03.92 *****************************************************************************/ static void ui_invHelp(Widget button, Boolean fromMain, caddr_t call_data) { Widget ui_invHBox,ui_invHelp,doneButton,lab[10]; Arg args[5]; Position x, y; Dimension width, height; Cardinal n; char buf[80]; /* set Popup arguments */ n = 0; XtSetArg(args[0], XtNwidth, &width);n++; XtSetArg(args[1], XtNheight, &height);n++; XtGetValues(button, args, n); XtTranslateCoords(button, (Position)(width), (Position)(height), &x, &y); n = 0; XtSetArg(args[n], XtNx, x);n++; XtSetArg(args[n], XtNy, y+100);n++; /* Now create Popup */ ui_invHelp = XtCreatePopupShell("help", transientShellWidgetClass, ui_toplevel, args, n); ui_invHBox = XtCreateManagedWidget("form", formWidgetClass, ui_invHelp, NULL, 0); doneButton = ui_xCreateButtonItem("done", ui_invHBox, NULL, NULL); XtAddCallback(doneButton, XtNcallback, (XtCallbackProc) ui_inv_helpDone, NULL); if(fromMain){ sprintf(buf,"Start/continue inversion with 'STEP'"); lab[0] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,doneButton); sprintf(buf,"Halt inversion run anytime with 'STOP'"); lab[1] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[0]); sprintf(buf,"Reset inversion with 'NEW'"); lab[2] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[1]); sprintf(buf,"Change parameters with 'SETUP'"); lab[3] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[2]); sprintf(buf,"After SETUP continue with 'STEP',"); lab[4] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[3]); sprintf(buf," or restart with 'NEW','STEP'"); lab[5] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[4]); sprintf(buf,"HINT: If inversion is performed on an untrained net,"); lab[6] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[5]); sprintf(buf," or on a trained net with an average error of more than 0.05,"); lab[7] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[6]); sprintf(buf," the algorithm is very likely not to converge !!"); lab[8] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[7]); }else{ sprintf(buf,"eta : The learn parameter; should range from 1.0 to 10.0"); lab[0] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,doneButton); sprintf(buf,"delta_max : The maximum allowed error for a output unit"); lab[1] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[0]); sprintf(buf,"Input pattern: The initial activation for all input units"); lab[2] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[1]); sprintf(buf,"2nd approx : The degree to which the target input pattern"); lab[3] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[2]); sprintf(buf," is dependent of the initial input pattern"); lab[4] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[3]); sprintf(buf," good values range from 0.2 to 0.8"); lab[5] = ui_xCreateLabelItem(buf,ui_invHBox,strlen(buf)*8,NULL,lab[4]); } /* Display popup now */ ui_checkWindowPosition(ui_invHelp); XtPopup(ui_invHelp, XtGrabExclusive); XFlush(ui_display); } /***************************************************************************** FUNCTION : ui_set_IO_units PURPOSE : create a chain of input units and the corresponding pattern NOTES : RETURNS : UPDATE : 29.01.92 *****************************************************************************/ static int ui_set_IO_units(void) { int next; int u_type; struct PosType position; struct UnitList *IUnit,*OUnit,*dummy1,*dummy2; int i_count = 0, o_count = 0, i, max_no; if((next = krui_getFirstUnit()) == 0)return(0); IUnit = (struct UnitList *) malloc(sizeof(struct UnitList)); inputs = IUnit; IUnit->prev = NULL; OUnit = (struct UnitList *) malloc(sizeof(struct UnitList)); outputs = OUnit; IUnit->prev = NULL; max_no = krui_getNoOfUnits(); for(i=1; i<= max_no; i++){ u_type = krui_getUnitTType(next); if(u_type == INPUT){ i_count++; krui_getUnitPosition(next,&position); dummy1 = IUnit; IUnit->no = next; IUnit->gridPos = position; IUnit->act = (FlintType)INPUT_PAT; IUnit->i_act = (FlintType)INPUT_PAT; if(INPUT_PAT == 1.0) IUnit->im_act = 9.2102404; /* = -ln(1/0.9999 - 1); */ else if(INPUT_PAT == 0.0) IUnit->im_act = -9.2102404; /* = -ln(1/0.0001 - 1); */ else IUnit->im_act =(FlintType)( -log((double)(1.0/INPUT_PAT - 1.0))); IUnit->next = (struct UnitList *) malloc(sizeof(struct UnitList)); IUnit = IUnit->next; IUnit->prev = dummy1; }else if(u_type == OUTPUT){ o_count++; krui_getUnitPosition(next,&position); dummy2 = OUnit; OUnit->no = next; OUnit->gridPos = position; OUnit->act = 0.0; OUnit->next = (struct UnitList *) malloc(sizeof(struct UnitList)); OUnit = OUnit->next; OUnit->prev = dummy2; } next=krui_getNextUnit(); } if(i_count == 0 || o_count == 0){ /* Stop inversion if no input or output units are defined */ return(1); }else{ /* Finish the pointer chain */ dummy1->next = NULL; dummy2->next = NULL; return(0); } } /***************************************************************************** FUNCTION : ui_closeDisplay PURPOSE : closing all widgets for inversion NOTES : RETURNS : UPDATE : 29.01.92 *****************************************************************************/ static void ui_closeDisplay(Widget w, caddr_t call_data) { if(INV_RUNNING){ ui_confirmOk("Stop inversion run before quiting !"); return; } XtDestroyWidget(ui_InvRootWidget); INVERS_CREATED = 0; inputs = NULL; outputs = NULL; } /***************************************************************************** FUNCTION : ui_invNew PURPOSE : restart the inversion NOTES : RETURNS : UPDATE : 11.02.92 *****************************************************************************/ static void ui_invNew(Widget w, caddr_t call_data) { struct UnitList *IUnit, *OUnit; IUnit = inputs; while(IUnit != NULL){ IUnit->act = (FlintType)INPUT_PAT; IUnit->i_act = (FlintType)INPUT_PAT; if(INPUT_PAT == 1.0) IUnit->im_act = 9.2102404; /* = -ln(1/0.9999 - 1); */ else if(INPUT_PAT == 0.0) IUnit->im_act = -9.2102404; /* = -ln(1/0.0001 - 1); */ else IUnit->im_act = (FlintType)(-log((double)(1.0/INPUT_PAT - 1.0))); IUnit = IUnit->next; } OUnit = outputs; while(OUnit != NULL){ OUnit->act = 0.0; OUnit->i_act = 0.0; OUnit = OUnit->next; } ui_drawInput(); INV_NEW = 1; } /***************************************************************************** FUNCTION : ui_invEvent PURPOSE : event handler for graphic window NOTES : RETURNS : UPDATE : 20.02.92 *****************************************************************************/ static void ui_invEvent(Widget w, Display *display, XEvent *event) { switch (event->type){ case Expose: if (event->xexpose.count == 0) ui_drawInput(); break; default: break; } } /***************************************************************************** FUNCTION : ui_drawInput PURPOSE : drawing the input units NOTES : RETURNS : UPDATE : 29.01.92 *****************************************************************************/ static void ui_drawInput(void) { int next; int u_type; int dx,dy; int procent_value; struct PosType position,pixpos,pixpos2; struct UnitList *IUnit, *OUnit; /* do nothing if no net is loaded */ if((next = krui_getFirstUnit()) == 0)return; /* prepare window for drawing */ displayPtr->frozen = FALSE; XClearWindow(inv_display,displayPtr->drawable); if(ui_col_monochromeMode){ XSetBackground(inv_display,ui_gc, ui_backgroundColor); XSetForeground(inv_display, ui_gc,ui_textColor); /* draw rectangle for EACH input/output unit */ do{ u_type = krui_getUnitTType(next); if(u_type == OUTPUT || u_type == INPUT){ krui_getUnitPosition(next,&position); ui_drawGrowingThing(displayPtr, position, -100); } }while((next=krui_getNextUnit()) != 0); }else{ XSetBackground(inv_display,ui_gc, ui_backgroundColor); XSetForeground(inv_display, ui_gc, ui_editColor[UI_BLACK]); XSetFunction(inv_display, ui_gc, GXcopy); } /* draw activation of input units */ IUnit = inputs; do{ position.x = displayPtr->gridSize * (IUnit->gridPos.x-displayPtr->origin.x) + displayPtr->gridSize/2; position.y = displayPtr->gridSize * (IUnit->gridPos.y-displayPtr->origin.y) + displayPtr->gridSize/2; procent_value = (int)(100.0*IUnit->act); if(ui_col_monochromeMode){ pixpos = ui_utilPixUpperLeft(displayPtr,IUnit->gridPos); pixpos2 = ui_utilPixLowerRight(displayPtr,IUnit->gridPos,0); dx = dy = (int)((float)(pixpos2.x - pixpos.x)*IUnit->act); pixpos.x += (int)((float)(pixpos2.x-pixpos.x)*0.5*(1.0 - IUnit->act)+0.5); pixpos.y += (int)((float)(pixpos2.y-pixpos.y)*0.5*(1.0 - IUnit->act)+0.5); XFillRectangle(inv_display, displayPtr->drawable, ui_gc, pixpos.x,pixpos.y,(unsigned int) dx,(unsigned int) dy); }else{ pixpos = ui_utilPixUpperLeft(displayPtr,IUnit->gridPos); pixpos2 = ui_utilPixLowerRight(displayPtr,IUnit->gridPos,0); XSetForeground(inv_display, ui_gc, ui_col_rangePixels[ui_col_steps+procent_value*ui_col_steps DIV 100]); ui_xDeleteRect(inv_display, displayPtr->drawable, ui_gc,pixpos,pixpos2); } IUnit = IUnit->next; }while(IUnit != NULL); /* draw activation of output units */ OUnit = outputs; do{ position.x = displayPtr->gridSize * (OUnit->gridPos.x-displayPtr->origin.x) + displayPtr->gridSize/2; position.y = displayPtr->gridSize * (OUnit->gridPos.y-displayPtr->origin.y) + displayPtr->gridSize/2; procent_value = (int)(100.0*OUnit->act); if(NOT ui_col_monochromeMode){ pixpos = ui_utilPixUpperLeft(displayPtr,OUnit->gridPos); pixpos2 = ui_utilPixLowerRight(displayPtr,OUnit->gridPos,0); XSetForeground(inv_display, ui_gc, ui_col_rangePixels[ui_col_steps+procent_value*ui_col_steps DIV 100]); ui_xDeleteRect(inv_display, displayPtr->drawable, ui_gc,pixpos,pixpos2); }else{ pixpos = ui_utilPixUpperLeft(displayPtr,OUnit->gridPos); pixpos2 = ui_utilPixLowerRight(displayPtr,OUnit->gridPos,0); dx = dy = (int)((float)(pixpos2.x - pixpos.x)*OUnit->act); pixpos.x += (int)((float)(pixpos2.x-pixpos.x)*0.5*(1.0 - OUnit->act)+0.5); pixpos.y += (int)((float)(pixpos2.y-pixpos.y)*0.5*(1.0 - OUnit->act)+0.5); XFillRectangle(inv_display, displayPtr->drawable, ui_gc, pixpos.x,pixpos.y,(unsigned int) dx,(unsigned int) dy); } OUnit = OUnit->next; }while(OUnit != NULL); /* drawing finished */ XFlush(inv_display); displayPtr->frozen = TRUE; } /***************************************************************************** FUNCTION : ui_start_inversion PURPOSE : Program to start inversion NOTES : callback from the control panel RETURNS : UPDATE : 29.01.92 ******************************************************************************/ static void ui_start_inversion(Widget button, caddr_t call_data) { if (ui_workProcId) XtRemoveWorkProc(ui_workProcId); /* kill old workProc */ ui_workType = 99; INV_RUNNING = 1; ui_workProcId = XtAppAddWorkProc(ui_appContext, (XtWorkProc) ui_do_inversion,NULL); } /***************************************************************************** FUNCTION : ui_stop_inversion PURPOSE : Program to stop inversion NOTES : callback from the control panel RETURNS : UPDATE : 29.01.92 ******************************************************************************/ static void ui_stop_inversion(Widget button, caddr_t call_data) { if(ui_workProcId){ INV_RUNNING = 0; ui_drawInput(); printf("cycle %d inversion error %f, %d error units left\n", INV_cycle,INV_error,INV_units); XtRemoveWorkProc(ui_workProcId); /* kill old workProc */ ui_workProcId = (XtWorkProcId) NULL; } } /***************************************************************************** FUNCTION : ui_do_inversion PURPOSE : Program for actual inversion algorithm NOTES : callback from the control panel RETURNS : UPDATE : 29.01.92 ******************************************************************************/ static Boolean ui_do_inversion(Widget button, caddr_t call_data) { struct UnitList *OUnit; struct SelectionType *SelDummy; int dummy; double old_err; int selUnits, err_units; int err; static int growing_errors = 0; /* set output pattern */ if(INV_NEW){ INV_cycle = 0; selUnits = 0; if(krui_getNoOfPatterns() == 0){ ui_confirmOk("Please load patterns first !"); INV_RUNNING = 0; return(TRUE); } OUnit = outputs; while(OUnit != NULL){ if((SelDummy = ui_sel_lookForItem(OUnit->no)) != NULL){ OUnit->i_act = 1.0; OUnit->act = 1.0; selUnits++; }else{ OUnit->i_act = 0.0; OUnit->act = 0.0; } OUnit = OUnit->next; } if(!selUnits){ ui_confirmOk("No target output selected !!"); INV_RUNNING = 0; return(TRUE); } INV_NEW = 0; } /* do the inversion */ if((err = krui_initInversion()) < 0){ printf("init returned error %d\n",err); INV_RUNNING = 0; return(TRUE); } INV_cycle++; err_units = 0; old_err = INV_error; krui_inv_forwardPass(inputs); INV_error = krui_inv_backwardPass(INV_eta,INV_delta_max,&err_units,RATIO, inputs,outputs); INV_units = err_units; if((dummy=(INV_cycle%50)) == 0) printf("cycle %d inversion error %f still %d error unit(s)\n", INV_cycle,INV_error,INV_units); if(old_err<= INV_error)growing_errors++; else growing_errors = 0; /* if(growing_errors > 50){ growing_errors = 0; ui_drawInput(); ui_confirmOk(" Inversion error does not diminish!\n Net might not be properly trained !"); INV_RUNNING = 0; return(TRUE); } */ /* check the result of this inversion step */ if(INV_units > 0){ /* while still one unit has an error > delta_max return FALSE, */ /* to start another cycle */ return(FALSE); }else{ /* algorithm has converged, display discovered activation pattern */ printf("cycle %d inversion error %f, %d error units left\n", INV_cycle,INV_error,INV_units); ui_drawInput(); INV_RUNNING = 0; return(TRUE); } } #endif