This is ART_LTM.m in view mode; [Download] [Up]
#import <objc/Object.h> #import "ART_LTM.h" #import "ART_Func.h" #define LTM_NODE_RESET 0 #define LTM_NODE_AVAIL 1 #define ART_READ(x) NXRead(stream,&x,sizeof(x)) #define ART_WRITE(x) NXWrite(stream,&x,sizeof(x)) #define ART_WRITE_ASCII(x) NXPrintf(stream,"%7.5f ",x) #define ART_WRITE_SLASH NXPrintf(stream,"\n") @implementation ART_LTM /* NXZone *zone; // Next Heap Zone int M,N; // field dimensions float **BU,**TD, // learning arrays *oldTD,*oldBU, d,h; // learning rate and integation stepsize int *Avail, // flag array for notation of reset nodes estab=1; // acount of established nodes */ + new { self=[super new]; return self; } - saveinto:(NXStream *)stream as:(int)t { int i,j; switch(t) { case ART_LTM_BIN: ART_WRITE(estab); for (i=0; i<M; i++) for (j=0; j<estab; j++) ART_WRITE(BU[i][j]); for (j=0; j<estab; j++) for (i=0; i<M; i++) ART_WRITE(TD[j][i]); break; case ART_LTM_ASCII: NXPrintf(stream,"TD %d X ",estab); NXPrintf(stream,"%d \n",M); for (j=0; j<estab; j++) { for (i=0; i<M; i++) ART_WRITE_ASCII(TD[j][i]); ART_WRITE_SLASH; } NXPrintf(stream,"BU %d X ",estab); NXPrintf(stream,"%d \n",M); for (j=0; j<estab; j++) { for (i=0; i<M; i++) ART_WRITE_ASCII(BU[i][j]); ART_WRITE_SLASH; } break; } return self; } - loadfrom:(NXStream *)stream { int i,j; ART_READ(estab); for (i=0; i<M; i++) for (j=0; j<estab; j++) ART_READ(BU[i][j]); for (j=0; j<estab; j++) for (i=0; i<M; i++) ART_READ(TD[j][i]); return self; } // init LTM array and additionals - init:(int)M_dim of:(int)N_dim { int i,j; [super init]; zone=[self zone]; M=M_dim; N=N_dim; // Bottum up Matrix which transforms patterns // from F2 to F2 BU[i][j] BU=(float **) NXZoneMalloc(zone,M*sizeof(float *)); for (i=0; i<M; i++) BU[i]=(float *) NXZoneMalloc(zone,N*sizeof(float)); // Top down Matrix which transforms patterns // from F2 to F1 TD[j][i] TD=(float **) NXZoneMalloc(zone,N*sizeof(float *)); for (j=0; j<N; j++) TD[j]=(float *) NXZoneMalloc(zone,M*sizeof(float)); oldBU=NXZoneMalloc(zone,M*sizeof(float)); oldTD=NXZoneMalloc(zone,M*sizeof(float)); Avail=NXZoneMalloc(zone,N*sizeof(int)); return self; } // free all allocated memory - free { int i,j; zone=[self zone]; for (i=0; i<M; i++) NXZoneFree(zone,BU[i]); NXZoneFree(zone,BU); for (j=0; j<N; j++) NXZoneFree(zone,TD[j]); NXZoneFree(zone,TD); NXZoneFree(zone,oldTD); NXZoneFree(zone,oldBU); NXZoneFree(zone,Avail); return [super free]; } // set the central parameter -set_d:(float)learnrate h:(float)stepsize { d=( learnrate > 1.0 ) ? 0.9 : ( ( learnrate < 0.0 ) ? 0.9 : learnrate ) ; h=stepsize; return self; } // give away the weights of a single F2 node - zero_template:(int)template with:(float)BU_scale { int i; for (i=0; i<M; i++) BU[i][template]=BU_scale/((1.0-d)*sqrt((float)M)); for (i=0; i<M; i++) TD[template][i]=0.0; return self; } // give away all weights - set_zero_with:(float)BU_scale { int j; for (j=0; j<N; j++) [self zero_template:j with:BU_scale]; estab=1; return self; } // transform a pattern from F1 to F2, seems like a korrelation - (int)korrelate_with:(float *)P to:(float *)Y { int i,j; for (j=0; j < estab; j++) { Y[j]=0.0; if ( Avail[j] ) for (i=0; i<M; i++) Y[j] += BU[i][j]*P[i]; } return estab-1; } // retrun a pointer to the TD array of M from a F2 node - (float *)TD_of:(int)j { return TD[j]; } // returns a pointer to the BU array of N from a F1 node - (float *)BU_of:(int)i { return BU[i]; } // set a vector of dim to the TD[j] array of LTM - set:(float *)Vec of:(int)dim to_TD_of:(int)j { int i; for (i=0;i<dim;i++) TD[j][i]=Vec[i]; return self; } // set a vector of dim to the BU[i] array of LTM - set:(float* )Vec of:(int)dim to_BU_of:(int)i { int j; for (j=0;j<dim;j++) BU[i][j]=Vec[j]; return self; } // declaire a Node as stable as iis norm excceds the thresh // and if the node is already learned - (BOOL)is:(int)Node stable:(float)thresh { if (Node>=(estab-1)) return NO; return ( (thresh < (L2_norm(TD[Node],M)*(1-d)) ) ? YES:NO ); } // methods concern the reset state of the F2 nodes // prepare for a new input pattern -(int)newPattern { int j; for (j=0; j < (estab); j++) Avail[j]=LTM_NODE_AVAIL; return estab-1; } // reset a certain node in case of the rho mismatch -(int)resetNode:(int)j { Avail[j]=LTM_NODE_RESET; return estab-1; } - (BOOL)NodeAvail:(int)i; { return ( Avail[i]==LTM_NODE_AVAIL ) ? YES:NO; } // returns the amount of etablished F2 nodes -(int)estabNodes { return estab-1; } // set the estab var to a new value - setestabNodes:(int)newestab { estab=newestab+1; return self; } // perform the learning facility of the LTM array - (float)learnPattern:(float *)Learn_Vec toNode:(int)F2_on { int i; float BUdiff=0.0,TDdiff=0.0; float tmp=0.0; float delta1, delta2, delta3, delta4; float zt1,zt2; if (F2_on >= (estab-1) ) estab++; for (i=0; i<M; i++) { oldBU[i]=BU[i][F2_on]; oldTD[i]=TD[F2_on][i]; zt1=d; /* Obacht */ zt2=Learn_Vec[i]; // Runge Kutta calculation of the learn DGL tmp=BU[i][F2_on]; delta1 = h * (zt1*(zt2-(tmp))); delta2 = h * zt1*(zt2-(tmp+ delta1/2.0)); delta3 = h * zt1*(zt2-(tmp+ delta2/2.0)); delta4 = h * zt1*(zt2-(tmp+ delta3)); BU[i][F2_on]=(float)(tmp+(delta1+2.0*delta2+2.0*delta3+delta4)/6.0); tmp=TD[F2_on][i]; delta1 = h * (zt1*(zt2-(tmp))); delta2 = h * zt1*(zt2-(tmp+ delta1/2.0)); delta3 = h * zt1*(zt2-(tmp+ delta2/2.0)); delta4 = h * zt1*(zt2-(tmp+ delta3)); TD[F2_on][i]=(float)(tmp+(delta1+2.0*delta2+2.0*delta3+delta4)/6.0); // BU[i][F2_on]=RungeKutta(i,BU[i][F2_on],h); // TD[F2_on][i]=RungeKutta(i,TD[F2_on][i],h); BUdiff += fabs(oldBU[i]-BU[i][F2_on]); } TDdiff=vec_diff(TD[F2_on],oldTD,M); return (BUdiff+TDdiff); } /* // functions of the LTM learning facility float dTD(int i, float z) { return(zt1*(zt2-z)); } float dBU(int i, float z) { return(zt1*(zt2-z)); } float RungeKutta( int i,float x,float h) { float delta1, delta2, delta3, delta4; delta1 = h * dTD(i,x); delta2 = h * dTD(i,x + delta1/2.0); delta3 = h * dTD(i,x + delta2/2.0); delta4 = h * dTD(i,x + delta3); return(x+(delta1+2.0*delta2+2.0*delta3+delta4)/6.0); } */ @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.