This is ARTDoc.m in view mode; [Download] [Up]
// the great ART Document Object #import "ARTDoc.h" #import "Controller.h" #import "Pattern.h" #import "ART_Animator.h" #import "ART2_Basic.h" #import "ART_STM.h" #import <appkit/Application.h> #import <appkit/Control.h> #import <appkit/TextField.h> #import <appkit/Window.h> #import <appkit/Panel.h> #import <appkit/Cursor.h> #import <appkit/Matrix.h> #import <appkit/Cell.h> #import <stdlib.h> #import <string.h> #import <objc/NXStringTable.h> #import <libc.h> // For random(), etc... #import <dpsclient/wraps.h> // For PS and DPS function prototypes #define frand() ((float) rand() / (RAND_MAX+1.0)) /* int PatRow,PatCol,PatDim,PatNum; int F2_on=ART_F2_OFF; char buf[256]; */ // Animator mesages macro #define A_MSG(F_msg) [[Animator F_msg] setStringValue:buf] // preform states #define ART_PERFORM_NEW 0 #define ART_PERFORM_PRE 1 #define ART_PERFORM_SEARCH 2 #define ART_PERFORM_MATCH 3 #define ART_PERFORM_LEARN_EXOR 4 #define ART_PERFORM_LEARN_ONE 5 #define ART_PERFORM_LEARN_STABLE 6 int perform_flag=ART_PERFORM_NEW; #define ART_GO 0 #define ART_STOP 1 #define STEP if (go_flag) @implementation ARTDoc static void newLocation(NXPoint *p) { static count = 0; p->x += (20.0 * count); p->y -= (25.0 * count); count = (count > 10)? 0 : count+1; } int DimMtx(int M,int t) { int i,td=t,tu=t; for (i=M-1;i--;) { if (0.0==fmod( (double)M,(double)td )) return td; if (0.0==fmod( (double)M,(double)tu )) return tu; td--; tu++; td=( td==1 ) ? 2:td; tu=( tu==M ) ? M-1:tu; } return 0; } - init { return [self initFromFile:NULL]; } - initFromFile:(const char *)file { NXStream *stream; NXRect theFrame; [super init]; [NXApp loadNibSection:"ARTDoc.nib" owner:self]; [window setDelegate:self]; [window getFrame:&theFrame]; newLocation(&theFrame.origin); [window moveTo:theFrame.origin.x :theFrame.origin.y]; // getting the object pointer //Control=[NXApp delegate]; Animator=[[NXApp delegate] Animator_id]; Pat=[[NXApp delegate] Pattern_id]; stringTable=[[NXApp delegate] stringTable]; // calc the pattern parameter PatDim=[Pat Dimension]; PatNum=[Pat Quantity]-1; // install SearchArray [self setSearchArray]; // install the corresponding ART Modul ARTModul=[ART2_Basic new]; artp = (struct ARTModulDefs *)ARTModul; if (file) { stream=NXMapFile(file,NX_READONLY); if (stream) { NX_DURING [ARTModul loadfrom:stream]; NXCloseMemory(stream,NX_FREEBUFFER); //NX_VALRETURN(self); NX_HANDLER NX_DURING NXCloseMemory(stream,NX_FREEBUFFER); NX_HANDLER // ignore any error at this point NX_ENDHANDLER return nil; NX_ENDHANDLER } else return nil; PatDim=artp->M; //[self ARTState]; } // of if file else // default with the corresponding dimension [ARTModul init_M:PatDim N:(int)[Pat Quantity]]; perform_flag=ART_PERFORM_NEW; go_flag=ART_STOP; disp_flag=ART_PAT_DISP; // update the animator PatRow=DimMtx(PatDim,(int)sqrt(PatDim)); PatCol=(int)PatDim/PatRow; [self setAnimator]; // show the Document //[self ARTState]; [self getARTDefs]; [window makeKeyAndOrderFront:nil]; return self; } - free { NXZoneFree([self zone],SearchArray); [ARTModul free]; return [super free]; } - setSearchArray { int i,q; q=[Pat Quantity]; if (SearchArray) NXZoneFree([self zone],SearchArray); SearchArray=NXZoneMalloc([self zone],q*sizeof(int)); for (i=0;i<q;i++) SearchArray[i]=0; [queueOut setBackgroundGray:NX_LTGRAY]; return self; } - (BOOL)noSearch { int i,q; //(if (!SearchArray) return NO; q=[Pat Quantity]; for (i=0;i<q && (1==SearchArray[i]);i++); return (i==(q)) ? YES:NO; } - setAnimator { [Animator setDispMode:disp_flag]; [Animator setRow:PatRow Col:PatCol]; [Animator setDim:PatDim Mag:[Pat Maximum]*1.1 zMax:1.0/(1-artp->d)]; [Animator setInVec:artp->zeroP]; [Animator setPreVec:artp->zeroP]; [Animator setTmpVec:artp->zeroP]; [Animator showAll]; return self; } - setFileName:(char *)aName { if (fileName) free(fileName); fileName = (char *)malloc(strlen(aName)+1); strcpy(fileName,aName); [window setTitleAsFilename:fileName]; return self; } - (char *)fileName { return fileName; } - save:sender { int fd; NXStream *stream; volatile BOOL hadAnError = NO; if (fileName) { fd = open(fileName, O_CREAT | O_WRONLY | O_TRUNC, 0666); stream = NXOpenFile(fd, NX_WRITEONLY); if (stream) { NX_DURING // NXWRITE(stream,%s,[self name]); [ARTModul saveinto:stream]; NXFlush(stream); NXClose(stream); close(fd); NX_HANDLER hadAnError = YES; NX_DURING NXFlush(stream); NXClose(stream); close(fd); NX_HANDLER /* ignore any error at this point */ NX_ENDHANDLER NX_ENDHANDLER } // if stream else hadAnError = YES; // message in case of an error if (hadAnError) { NXRunAlertPanel(STRTAB("save alert title"), STRTAB("save alert message"), STRTAB("OK"), NULL, NULL,fileName); return nil; } else { [window setDocEdited:NO]; return self; } } //of if filename return nil; } - creatLTMdat:sender { int fd; NXStream *stream; char *p; if (fileName) { strcpy(buf,fileName); if (p = rindex(buf,'.')) { *++p = '\0'; strcat(buf,"LTMdat"); } fd = open(buf, O_CREAT | O_WRONLY | O_TRUNC, 0666); stream = NXOpenFile(fd, NX_WRITEONLY); // write only LTM weigths in ascii file with extension LTMdat [[ARTModul LTM] saveinto:stream as:ART_LTM_ASCII]; NXFlush(stream); NXClose(stream); close(fd); } return self; } - performNEW { int i; // get the NeXT Pattern and show if ([[NXApp delegate] Rand_sel]) PatNum=(int)(frand()*(float)[Pat Quantity]); else { PatNum++; PatNum=(PatNum>=[Pat Quantity]) ? 0:PatNum; } // assume that this pattern will be coded without search SearchArray[PatNum]=1; // show the pattern number and clean the textcells sprintf(buf,STRTAB("Input is pattern No.: %d"),PatNum); A_MSG(F0msg); sprintf(buf," "); A_MSG(F1msg); A_MSG(F2msg); [self updateARTDefs]; // Initialize ART & Animator and show input pattern [Animator setInVec:[Pat thePattern:PatNum]]; [Animator showInVec]; // Set preprocessed Pattern [ARTModul zeroSTMs]; [ARTModul setPattern:[Pat thePattern:PatNum]]; // hiding the previous template [Animator setTmpVec:[[ARTModul F0] get_U]]; [Animator showTmpVec]; // Preprocessing i=[ARTModul preproc]; // show Pattern and iterations [Animator setPreVec:[[ARTModul F0] get_P]]; [Animator showPreVec]; STEP { sprintf(buf,STRTAB("F0 stability after %d iterations"),i); A_MSG(F1msg); } // define the next task if (L2_norm([[ARTModul F0] get_P],artp->M)<0.01) perform_flag=ART_PERFORM_NEW; else perform_flag=ART_PERFORM_SEARCH; return self; } -performSEARCH { float sigT,sigI,sigS; // perform the search and in the search methode the exorproc F2_on=[ARTModul chooseF2]; STEP { if (F2_on==[[ARTModul LTM] estabNodes]) sprintf(buf,STRTAB("new template is choosen %d "),F2_on); else { if (artp->art2_mode) { switch(artp->set_type) { case ART_MIX: sprintf(buf,STRTAB("( Mixset ) choosen template is %d "),F2_on); break; case ART_SUP: sprintf(buf,STRTAB("( Superset ) choosen template is %d "),F2_on); break; case ART_SUB: sprintf(buf,STRTAB("( Subset ) choosen template is %d "),F2_on); break; case ART_IDE: sprintf(buf,STRTAB("( Identical ) choosen template is %d "),F2_on); break; } // STOP /* sigS=[ARTModul significance_of:[[ARTModul F0x] get_P]]; sigT=[ARTModul significance_of:[[ARTModul F0x] get_Q]]; sigI=[ARTModul significance_of:[[ARTModul F0 ] get_P]]; sprintf(buf,STRTAB("In %5.3f Tmp %5.3f Exor %5.3f "), sigI,sigT,sigS); A_MSG(F1msg); if (sigS==0.0) sprintf(buf,"Identical set"); else { sprintf(buf,"Mixed set"); if ( fabs(sigS+sigT-sigI) < 1.0) sprintf(buf,"Super set"); if ( fabs(sigS+sigI-sigT) < 1.0) sprintf(buf,"Sub set"); } [Animator setPreVec:[[ARTModul F0x] get_P]]; [Animator showPreVec]; */ // STOP } else sprintf(buf,STRTAB("choosen template is %d "),F2_on); } A_MSG(F2msg); } // of STEP perform_flag=ART_PERFORM_MATCH; return self; } - performMATCH { // iterate F1 and decide of good matching [ARTModul compair]; if ([ARTModul match]) { // show template is go and step by step modus [Animator setTmpVec:[[ARTModul LTM] TD_of:F2_on]]; [Animator showTmpVec]; [ARTModul markActiveNode]; // // extended mode only tricky one // In case of extended mode, a real subset input and a stable // template, the template will be completely erased to increase // the recoding time of the subset to its superset template if (artp->art2_mode) if( ![ARTModul newNode] && [[ARTModul LTM] is:F2_on stable:artp->exor_thresh] && (artp->set_type==ART_SUB) ) [[ARTModul LTM] zero_template:F2_on with:artp->BU_inst]; // extended mode end // if ([ARTModul newNode]) [self setSearchArray]; perform_flag=ART_PERFORM_LEARN_ONE; return self; } else { STEP { [Animator setTmpVec:[[ARTModul LTM] TD_of:F2_on]]; [Animator showTmpVec]; sprintf(buf,STRTAB("bad match (%4.3f < %4.3f) reset of Node %d"), artp->r,artp->tmprho,F2_on); A_MSG(F2msg); } [[ARTModul LTM] resetNode:F2_on]; // finaly reset all nosearch labels [self setSearchArray]; perform_flag=ART_PERFORM_SEARCH; } return self; } -performLEARN_ONE { float z; // perform learning and set window edited z=[ARTModul learning]; [Animator showTmpVec]; [window setDocEdited:YES]; STEP { sprintf(buf,STRTAB("good match (%4.3f > %4.3f) stable %4.3f"), artp->r,artp->tmprho,z); A_MSG(F2msg); } // // define NeXT task if (artp->learn_mode) perform_flag=ART_PERFORM_LEARN_STABLE; else // only in extended mode if (artp->art2_mode) perform_flag=ART_PERFORM_LEARN_EXOR; else perform_flag=ART_PERFORM_NEW; return self; } -performLEARN_STABLE { float z; // perform the stable learning in the slow modus i.e. // after every learning the F1 is set zero and will be newly // iterated [[ARTModul F1] set_zero]; [ARTModul compair]; z=[ARTModul learning]; // STEP { sprintf(buf,STRTAB("good match (%4.3f > %4.3f) stable %4.3f"), artp->r,artp->tmprho,z); A_MSG(F2msg); } [Animator showTmpVec]; // // looking for stability of the weights and define NeXT task if( (artp->z_diff<z) && [ARTModul match] ) perform_flag=ART_PERFORM_LEARN_STABLE; else if (artp->art2_mode) // only in extended mode : perform_flag=ART_PERFORM_LEARN_EXOR; else perform_flag=ART_PERFORM_NEW; return self; } -performLEARN_EXOR { // Note that the EXOR Pattern P is the part of the input // that the template need additional to figure the input. // Hence the EXOR pattern should be presented to the system // virually as a new pattern. This pattern is also orthogonal // to its source. // The input Pattern should be : // 1. superset // 2. stable learned template // if ( (artp->set_type==ART_SUP) && [ [ARTModul LTM] is:F2_on stable:artp->exor_thresh ] ) { // in this case the Pointer to F0x is set to F1 so that // for further search the vector P of F0x, containing // the processed EXOR-pattern is going to be treated as // a new pattern with full ART ability. L2_norm_Vec([[ARTModul F0x] get_P], [[ARTModul F0 ] get_P],artp->M); // [[ARTModul LTM ] newPattern]; perform_flag=ART_PERFORM_SEARCH; // // show the action and clean template textcell and graph STEP { sprintf(buf,STRTAB("Exor pattern features")); A_MSG(F1msg); sprintf(buf," "); A_MSG(F2msg); } // hiding the previous template [Animator setTmpVec:artp->zeroP]; [Animator showTmpVec]; // show Pattern and iterations [Animator setPreVec:[[ARTModul F0] get_P]]; [Animator showPreVec]; } else perform_flag=ART_PERFORM_NEW; return self; } - step:sender { switch(perform_flag) { case ART_PERFORM_NEW: [self performNEW]; break; case ART_PERFORM_MATCH: [self performMATCH]; break; case ART_PERFORM_SEARCH: if ([ARTModul resizeART]) { sprintf(buf,STRTAB("ART is resized to %d"),artp->N); [queueOut setStringValue:buf]; } [self performSEARCH]; break; case ART_PERFORM_LEARN_ONE: [self performLEARN_ONE]; [self ARTState]; break; case ART_PERFORM_LEARN_STABLE: [self performLEARN_STABLE]; break; case ART_PERFORM_LEARN_EXOR: [self performLEARN_EXOR]; break; } return self; } void PerformIt(DPSTimedEntry te, double timeNow, void *data) { [(id)data animate]; } - animate { NXEvent dummyEvent; // For peeking at the event queue. do { [self step:nil]; } while ([NXApp peekNextEvent:NX_ALLEVENTS into:&dummyEvent waitFor:0.0 threshold:NX_BASETHRESHOLD] == NULL); return self; } - (BOOL)isPerforming { return (ART_GO==go_flag) ? YES:NO; } - (BOOL)matchWithPat { return ( [Pat Dimension]==artp->M ) ? YES:NO ; } - set_go { if (go_flag==ART_STOP) { // Call the PerformIt() function as often as possible... ARTTimedEntry=DPSAddTimedEntry(0.0, &PerformIt, self,NX_BASETHRESHOLD); go_flag=ART_GO; } return self; } - set_stop { if (go_flag==ART_GO) { DPSRemoveTimedEntry(ARTTimedEntry); // [self finishCycle]; go_flag=ART_STOP; } return self; } - stepPattern { do { [self step:nil]; } while (perform_flag!=ART_PERFORM_NEW); return self; } - finishCycle { while (perform_flag!=ART_PERFORM_NEW) { [self step:nil]; } return self; } - resetLTM:sender { // finish for n new pattern [self finishCycle]; [ARTModul resetLTM]; [self setSearchArray]; return self; } - ARTState { int i; char a[100]; int *PQ=artp->PatQueue; [inputOut setIntValue:PatNum]; // sprintf(buf,STRTAB("%d of %d"),[[ARTModul LTM] estabNodes],artp->N); // [estabOut setStringValue:buf]; [estabOut setIntValue:[[ARTModul LTM] estabNodes]]; buf[0]='\0'; for(i=0; PQ[i]!=ART_F2_OFF; i++) { sprintf(a,"%d ",PQ[i]); strcat(buf,a); } // for no search print out additional if (SearchArray[PatNum]==1) { sprintf(a,"no search"); strcat(buf,a); } // for no search amoung the patternwell highlight textfield if ([self noSearch]) [queueOut setBackgroundGray:NX_WHITE]; else [queueOut setBackgroundGray:NX_LTGRAY]; if (strlen(buf)) { [queueOut setStringValue:buf]; strcpy(a,buf); // Animator Output F0msg sprintf(buf,STRTAB("Input is pattern No.: %d"),PatNum); A_MSG(F0msg); // Animator Output F01msg sprintf(buf,"coding to : "); strcat(buf,a); A_MSG(F01msg); } return self; } - setRow:sender { int r=[RowIn intValue]; r=(r<1 || r>PatDim) ? PatRow:r; PatRow=DimMtx(PatDim,r); PatCol=(int)PatDim/PatRow; [RowIn setIntValue:PatRow]; [ColIn setIntValue:PatCol]; [Animator setRow:PatRow Col:PatCol ]; [Animator showAll]; return self; } - setCol:sender { int c=[ColIn intValue]; c=(c<1 || c>PatDim) ? PatCol:c; PatCol=DimMtx(PatDim,c); PatRow=(int)PatDim/PatCol; [RowIn setIntValue:PatRow]; [ColIn setIntValue:PatCol]; [Animator setRow:PatRow Col:PatCol]; [Animator showAll]; return self; } - setVecModus:sender { if (disp_flag!=ART_VEC_DISP) { disp_flag=ART_VEC_DISP; [Animator setDispMode:disp_flag]; [Animator showAll]; } return self; } - setPatModus:sender { if (disp_flag!=ART_PAT_DISP) { disp_flag=ART_PAT_DISP; [Animator setDispMode:disp_flag]; [Animator showAll]; } return self; } - setDelegate:anObject { return self; } // comunication - (int)inputPattern { return PatNum; } - (int)codesNodes { int i; for(i=0; artp->PatQueue[i]!=ART_F2_OFF; i++); return i; } - (int *)PatQueue { return artp->PatQueue; } - (int)F2Nodes { return [[ARTModul LTM] estabNodes]; } - (float *)theTemplate:(int)i { return [[ARTModul LTM] TD_of:i]; } // tricky delegations - windowDidBecomeMain:sender { [window makeFirstResponder:window]; if ([[NXApp delegate] document] != self) { [[NXApp delegate] stopAll]; if ([self matchWithPat]) { [[NXApp delegate] unlookCTRL]; if ([self isPerforming]) [[NXApp delegate] setGoState]; else { perform_flag=ART_PERFORM_NEW; [[NXApp delegate] setStopState]; } } else { [[NXApp delegate] lookCTRL]; [[NXApp delegate] MisMatchAlert]; } [[NXApp delegate] setDocument:self]; [self setAnimator]; } return self; } - windowDidResignMain:sender { //Animator=nil; //if (perform_flag!=ART_PERFORM_NEW) [self set_stop]; // if ([[NXApp delegate] document] == self) // [[NXApp delegate] setDocument:nil]; return self; } - windowDidMiniaturize:sender { return self; } - windowWillClose:sender { int choice; if ([window isDocEdited]) { if (!stringTable) stringTable = [[NXApp delegate] stringTable]; choice = NXRunAlertPanel( STRTAB("Close"), STRTAB("ART Save it?"), STRTAB("Yes"), STRTAB("No"), STRTAB("Cancel")); switch (choice) { case NX_ALERTALTERNATE: break; case NX_ALERTDEFAULT: [[NXApp delegate] save:nil]; break; case NX_ALERTOTHER: return nil; } } [self windowDidResignMain:nil]; [window setDelegate:nil]; [self set_stop]; [self free]; return sender; } - updateARTDefs // from the display and set the ARTModul { // ARTMode artp->art2_mode=[[ARTModeMtx selectedCell] tag]; // Learning artp->learn_mode=[[ARTLearnMtx selectedCell] tag]; // field const artp->a=MAX(0.1,MIN([f_a floatValue],50.0)); artp->b=MAX(0.1,MIN([f_b floatValue],50.0)); // special check cause there is a dependance between d and c // c has changed if (artp->c!=[f_c floatValue]) { artp->c=MAX(1E-03,MIN([f_c floatValue],(1.0-artp->d)/artp->d )); // artp->d=MAX(1E-03,MIN([f_d floatValue],1/(1.0+artp->c) )); } // d has changed if (artp->d!=[f_d floatValue]) { artp->d=MAX(1E-03,MIN([f_d floatValue],1/(1.0+artp->c) )); // artp->c=MAX(1E-03,MIN([f_c floatValue],(1.0-artp->d)/artp->d )); } // vigilance //if ([f_rho floatValue] > 1.0) artp->rho=1.0; //if ([f_rho floatValue] < 0.0) artp->rho=0.0; artp->rho=MAX(0.0,MIN([f_rho floatValue],0.9999999999999)); artp->rhoset=MAX(0.0,MIN([f_rhoset floatValue],1.0)); // thresh artp->theta=MAX(0.0,MIN([f_theta floatValue],1.0)); // integration artp->z_diff=MAX(1E-10,MIN([f_z_diff floatValue],1.0)); artp->h=MAX(1E-5,MIN([f_h floatValue],10.0)); // activity artp->ac_diff=MAX(1E-10,MIN([f_ac_diff floatValue],1.0)); // i_min has changed if (artp->i_min!=[f_min intValue]) artp->i_min=MAX(1,MIN([f_min intValue],artp->i_max)); // i_max has changed if (artp->i_max!=[f_max intValue]) artp->i_min=MAX(artp->i_min+1,MIN([f_max intValue],1000)); // BU artp->BU_inst=MAX(1E-10,MIN([f_BU_inst floatValue],1.0)); // and finaly [ARTModul update_syspara]; return self; } - getARTDefs // from the ARTModul and show { // ARTMode [ARTModeMtx selectCellWithTag:(artp->art2_mode)]; // Learning [ARTLearnMtx selectCellWithTag:(artp->learn_mode)]; // field const [f_a setFloatValue:artp->a]; [f_b setFloatValue:artp->b]; [f_c setFloatValue:artp->c]; [f_d setFloatValue:artp->d]; // vigilance [f_rho setFloatValue:artp->rho]; [f_rhoset setFloatValue:artp->rhoset]; // thresh [f_theta setFloatValue:artp->theta]; // integration [f_z_diff setFloatValue:artp->z_diff]; [f_h setFloatValue:artp->h]; // activity [f_ac_diff setFloatValue:artp->ac_diff]; [f_min setIntValue:artp->i_min]; [f_max setIntValue:artp->i_max]; // BU [f_BU_inst setFloatValue:artp->BU_inst]; // pattern parameter [DimOut setIntValue:PatDim]; [RowIn setIntValue:PatRow]; [ColIn setIntValue:PatCol]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.