/************************************************************************* Recfield.C Deterministic model for receptive fields with Hebbian and Anti-Hebbian learning. Last Uppate: 2/2000 *************************************************************************/ #include "nsl_include.h" #include "Recfield.h" #define pi 3.141592 /* no comment */ //#define arg11(i,j,k,l) i*y1+j,k*y1+l /* indices x1,y1,x1,y1 */ //#define arg12(i,j,k,l) i+j*x1,k+l*y1 /* indices x1,x2,y1,y2 */ //#define arg22(i,k,j,l) i*y2+j,k*y2+l /* indices x2,y2,x2,y2 */ RecfieldModel::RecfieldModel() : NslModel("RecfieldModel"), rf("recfield",this,5,5,5,5) { } Recfield::Recfield(nsl_string str,NslModule* parent, int x1,int x2,int y1,int y2) : NslModule(str,parent), a("a",this,x1,y1), b("b",this,x2,y2), w("w",this,x1,y1,x2,y2), q("q",this,x1,y1,x2,y2) { makeConn(); } void Recfield::makeConn() { nslConnect(a.g,w.g); nslConnect(b.g,q.g); nslConnect(w.e,q.e); nslConnect(q.pp,w.pp); } LayerA::LayerA(nsl_string str,NslModule* parent,int x1,int y1) : NslModule(str,parent), g("g",this,x1,y1,x1,y1), // (x1*y1, x1*y1); sp("sp",this), // spreading in layer 1 delta("delta",this) // height of the gaussian1 { } void LayerA::initRun() { int i, j, k, l; /* loops */ float d,dx,dy; int x1 = g.get_imax(); int y1 = g.get_jmax(); /* gaussian values (toroidal layers) */ for (i = 0; i < x1; i++) for (j = 0; j < y1; j++) for (k = 0; k < x1; k++) for (l = 0; l < y1; l++) { dx = fabs(i - k); if (dx > (x1 / 2)) dx = x1 - dx; dy = fabs(j - l); if (dy > (y1 / 2)) dy = y1 - dy; d = sqrt ( dx*dx + dy*dy ); g.elem(i,j,k,l) = delta.elem() * 1 / sp.elem() * exp(-pow((d / sp.elem()), 2)/2) ; } } LayerB::LayerB(nsl_string str,NslModule* parent,int x2,int y2) : NslModule(str,parent), g("g",this,x2,y2,x2,y2), // (x2*y2, x2*y2); sp("sp",this), // spreading in layer 2 delta("delta",this) // height of the gaussian2 { } void LayerB::initRun() { int i, j, k, l; /* loops */ float d,dx,dy; int x2 = g.get_imax(); int y2 = g.get_jmax(); for (i = 0; i < x2; i++) for (j = 0; j < y2; j++) for (k = 0; k < x2; k++) for (l = 0; l < y2; l++) { dx = fabs(i - k); if (dx > (x2 / 2)) dx = x2 - dx; dy = fabs(j - l); if (dy > (y2 / 2)) dy = y2 - dy; d = sqrt ( dx*dx + dy*dy ); g.elem(i,k,j,l) = delta.elem() * 1 / sp.elem() * exp(-pow((d / sp.elem()), 2)/2) ; } } ConnectW::ConnectW(nsl_string str,NslModule* parent, int x1,int x2,int y1,int y2) : NslModule(str,parent), w("w",this,x2,x1,y2,y1), // (x1*x2, y1*y2); g("g",this,x1,y1,x1,y1), // (x1*y1, x1*y1); e("e",this,x2,x1,y2,y1), // (x1*x2, y1*y2); pp("pp",this,x2,y2,x2,y2), // (x2*y2, x2*y2); beta("beta",this), // integration parameter for act ga("ga",this), // cubic decay term for w alpha("alpha",this), // to get the weights out from zero maxinitval("maxinitval",this), // weight maximum initial value seed("seed",this), // random seed randa("randa",this) { } void ConnectW::initRun() { int i, j, k, l; /* loops */ int max_rand; float d,dx,dy; /* calculation of the random maximum value */ max_rand = 0; for (i = 0; i < 1000; i++) { j = rand(); if ( j > max_rand) max_rand = j; } /* random seed */ srand(seed.elem()); /* randa: normalizes rand to 1 */ float mx = maxinitval.elem()/max_rand; /* weight initialization */ int x1 = w.get_imax(); int y1 = w.get_jmax(); int x2 = w.get_kmax(); int y2 = w.get_lmax(); for (i = 0; i < x1; i++) for (j = 0; j < x2; j++) for (k = 0; k < y1; k++) for (l = 0; l < y2; l++) w.elem(j,i,l,k) = mx*rand(); } void ConnectW::simRun() { convGauss(); modifyWeights(); } void ConnectW::convGauss() { int i, j, k, l, m, n, o, p; /* loops */ float sum, sum2; int x1 = g.get_imax(); int y1 = g.get_jmax(); int x2 = w.get_imax(); int y2 = w.get_jmax(); /* convolutions gaussian1 w p */ for (i = 0; i < x1; i++) for (j = 0; j < y1; j++) for (k = 0; k < x2; k++) for (l = 0; l < y2; l++) { sum = 0; for (m = 0; m < x1; m++) for (n = 0; n < y1; n++) { sum2 = 0; for (o = 0; o < x2; o++) for (p = 0; p < y2; p++) sum2 = sum2 + w.elem(o,m,p,n) * pp.elem(o,k,p,l); sum = sum + g.elem(i,j,m,n) * sum2; } e.elem(k,i,l,j) = sum; } } void ConnectW::modifyWeights() { int i, j, k, l, m, n, o, p; /* loops */ float sum, sum2; int x1 = g.get_imax(); int y1 = g.get_jmax(); int x2 = w.get_imax(); int y2 = w.get_jmax(); /* weight modification */ for (i = 0; i < x1; i++) for (j = 0; j < y1; j++) for (k = 0; k < x2; k++) for (l = 0; l < y2; l++) { sum = 0; for (m = 0; m < x1; m++) for (n = 0; n < y1; n++) sum = sum + g.elem(m, n, i, j) * e.elem(k,m,l,n); w.elem(k,i, l,j) = alpha.elem() + w.elem(k,i,l,j) * (1 + beta.elem() * ( sum - ga.elem() * w.elem(k,i,l,j) * w.elem(k,i,l,j) )); if (w.elem(k,i,l,j) < 0) cmd_out("no"); } } ConnectQ::ConnectQ(nsl_string str,NslModule* parent, int x1,int x2,int y1,int y2) : NslModule(str,parent), q("q",this,x2,y2,x2,y2), // (x2*y2, x2*y2); pp("pp",this,x2,y2,x2,y2), // (x2*y2, x2*y2); e("e",this,x2,x1,y2,y1), // (x1*x2, y1*y2); g("g",this,x2,y2,x2,y2), // (x2*y2, x2*y2); beta("beta",this), // integration parameter for act ga("ga",this), // cubic decay term for w alpha("alpha",this) // to get the weights out from zero { } void ConnectQ::initRun() { q = 0; } void ConnectQ::simRun() { convGauss(); modifyWeights(); } void ConnectQ::convGauss() { int i, j, k, l, m, n, o, p; /* loops */ float sum, sum2; int x2 = q.get_imax(); int y2 = q.get_jmax(); /* convolutions q gaussian2 */ for (i = 0; i < x2; i++) for (j = 0; j < y2; j++) for (k = 0; k < x2; k++) for (l = 0; l < y2; l++) { sum = 0; for (m = 0; m < x2; m++) for (n = 0; n < y2; n++) sum = sum + g.elem(i,m,j,n) * q.elem(m,k,n,l); pp.elem(i,k,j,l) = g.elem(i,k,j,l) - sum; } } void ConnectQ::modifyWeights() { int i, j, k, l, m, n, o, p; /* loops */ float sum, sum2; int x1 = e.get_imax(); int y1 = e.get_jmax(); int x2 = q.get_imax(); int y2 = q.get_jmax(); for (i = 0; i < x2; i++) for (j = 0; j < y2; j++) for (k = 0; k < x2; k++) for (l = 0; l < y2; l++) { sum = 0; for (m = 0; m < x1; m++) for (n = 0; n < y1; n++) sum = sum + e.elem(i,m,j,n) * e.elem(k,m,l,n); q.elem(i,k,j,l) = alpha.elem() + q.elem(i,k,j,l) * (1 + beta.elem() * (sum - ga.elem()*q.elem(i,k,j,l)*q.elem(i,k,j,l))); if (q.elem(i,k,j,l) < 0) cmd_out("ni"); } } AslSchemaModel _RecfieldModel("RecfieldModel");