• Non ci sono risultati.

Appendice Il listato della simulazione

N/A
N/A
Protected

Academic year: 2021

Condividi "Appendice Il listato della simulazione"

Copied!
50
0
0

Testo completo

(1)

Appendice

Il listato della simulazione

Di seguito andiamo a presentare il listato della simulazione comprensivo dei file più

importanti per il nostro lavoro seguendo la sequenza con cui sono stati esposti nel

paragrafo 3.3.2. Iniziamo con i file di estensione “.h” e “.cpp” della famiglia base di ARI:

ARI_3DObject.h e ARI_3DObject.cpp.

ARI_3DObject.h #ifndef __ARI_3D_OBJECT__ #define __ARI_3D_OBJECT__ #include <ARI_Vector3.h> #include <ARI_GLUtils.h>

#define ARI_3DO_RADIUS ARI_Vector3(0.5f,0.5f,0.5f)

#define ARI_3DO_FLAG_RENDER 1 #define ARI_3DO_FLAG_SETINPUT 2 #define ARI_3DO_FLAG_UPDATE 4 class ARI_3DObject { public: ARI_3DObject() {SetPosition(ARI_Vector3::GetZero()); SetRadius(ARI_3DO_RADIUS); SetFlags(ARI_FLAG_NULL); }

// Si occupa del rendering OpenGL. E' virtuale e di default disegna un cubo giallo (0.5).

virtual void Render();

//Si occupa delle operazioni da compiere a seguito del trigger di pre-update. Di default non //fa nulla.

virtual void SetInput() {}

//Si occupa delle operazioni di aggiornamento a seguito di un tempo dt di inter-frame. Di //default non fa nulla.

virtual void Update(double dt) {}

ARI_FLAG GetFlags() { return _flags; }

void SetFlags(ARI_FLAG flags) { ARI_FLAG_SET(_flags,flags); }

bool IsSetFlag(ARI_FLAG flags) { return

ARI_FLAG_ISSET(_flags,flags); }

void AddFlag(ARI_FLAG flags) { ARI_FLAG_ADD(_flags,flags); } void RemFlag(ARI_FLAG flags) { ARI_FLAG_REM(_flags,flags); }

(2)

void SetName(const ARI_String & name) { _name = name; }

ARI_String GetName() { return _name; }

void SetRadius(ARI_Vector3 radius) { _radius = radius; }

void SetSphereRadius(float radius) {

SetRadius(ARI_Vector3(radius,radius,radius) ); }

ARI_Vector3 GetRadius() { return _radius; }

void SetPosition(const ARI_Vector3 & position) { _position =

position; }

ARI_Vector3 GetPosition() { return _position; }

private:

//La collocazione geometrica ARI_Vector3 _position; ARI_Vector3 _radius; ARI_FLAG _flags; ARI_String _name; }; #endif ARI_3DObject.cpp #include "stdafx.h" #include <ARI_3DObject.h> #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

void ARI_3DObject::Render() {

glPushMatrix();

glTranslatef(_position.x, _position.y, _position.z); glEnable(GL_COLOR_MATERIAL) ;

glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); ARI_GLDrawColor(0.5);

ARI_GLDrawCube(_radius.x/2.0f, _radius.y/2.0f, _radius.z/2.0f); glDisable(GL_COLOR_MATERIAL);

glDisable(GL_LIGHT0); glDisable(GL_LIGHTING); glPopMatrix();

}

Le due classi che derivano da ARI_3DObject sono ARI_W e ARI_WGroup.

ARI_W.h

#ifndef __ARI_W__ #define __ARI_W__

#include <ARI_3DObject.h>

#include <ARI_FastDynamicArray.h>

#define ARI_W_TEMPLATE template<class OUTDATA, class CONNSPEC>

#define ARI_W_QUAL ARI_W<OUTDATA, CONNSPEC>

#define ARI_WCONNECTION_QUAL ARI_WConnection<OUTDATA, CONNSPEC>

#define ARI_W_InputList ARI_FastDynamicArray<ARI_WCONNECTION_QUAL * > #define ARI_W_OutputList ARI_FastDynamicArray<ARI_WCONNECTION_QUAL * >

#define ARI_W_RADIUS ARI_Vector3(0.5f,0.5f,0.5f)

struct ARI_WConnectionSpec {

(3)

}; ARI_W_TEMPLATE class ARI_W; ARI_W_TEMPLATE class ARI_WConnection { public: ARI_W_QUAL* _pWSrc; OUTDATA _output; CONNSPEC _connectionSpec; ARI_W_QUAL* _pWDest; }; ARI_W_TEMPLATE

class ARI_W: public ARI_3DObject { public: ARI_W() { SetOutput(NULL);AddFlag(ARI_3DO_FLAG_RENDER| ARI_3DO_FLAG_SETINPUT| ARI_3DO_FLAG_UPDATE); SetRadius(ARI_W_RADIUS);FirstWCInput();FirstWCOutput(); } virtual ~ARI_W(); void Detach();

OUTDATA GetOutput() {return _output;}

void SetInput();

void Update(double dt) {SetOutput(Process(dt));}

bool AddInputFrom(ARI_W_QUAL* pW, CONNSPEC* pConnectionSpec); bool AddOutputTo(ARI_W_QUAL*pW, CONNSPEC * pConnectionSpec)

{return pW->AddInputFrom(this, pConnectionSpec);} bool RemoveInputFrom(ARI_W_QUAL* pW);

bool RemoveOutputTo(ARI_W_QUAL* pW) {returnpW->RemoveInputFrom(this);}

void SetOutput(OUTDATA output) {_output = output;}

unsigned int CountWCInput() { return _inputList.Count(); }

void FirstWCInput() { _itInput =_inputList.First(); }

void NextWCInput() { _itInput++; }

bool EndWCInput() { return _itInput==_inputList.End();}

ARI_WCONNECTION_QUAL* GetWCInput() { return (*_itInput); }

unsigned int CountWCOutput() { return _outputList.Count(); }

(4)

void NextWCOutput() { _itOutput++; }

bool EndWCOutput() { return _itOutput == _outputList.End(); }

ARI_WCONNECTION_QUAL* GetWCOutput() { return (*_itOutput); }

protected:

ARI_W_OutputList _outputList; ARI_W_InputList _inputList; private:

virtual OUTDATA Process(double dt)=0;

OUTDATA _output; ARI_W_InputList::Iterator _itInput; ARI_W_OutputList::Iterator _itOutput; }; #include <ARI_W.inl> #endif ARI_WGroup.cpp #ifndef __ARI_W_GROUP__ #define __ARI_W_GROUP__ #include <ARI_W.h> #include <ARI_3DObject.h> #include <Urn.h> //#include <stdlib.h>

#define ARI_WGroup_WList ARI_FastDynamicArray<ARI_W_QUAL*>

#define ARI_WGROUP_TEMPLATE ARI_W_TEMPLATE

#define ARI_WGROUP_QUAL ARI_WGroup<OUTDATA, CONNSPEC>

#define ARI_PROJECTION_FLAG_NTON 1 #define ARI_PROJECTION_FLAG_1TO1 2 #define ARI_PROJECTION_FLAG_UNIRNDTON 4 #define ARI_PROJECTION_FLAG_GP1TO1 8 #define ARI_PROJECTION_FLAG_NTOUNIRND 16 struct ARI_ProjectionSpec { ARI_ProjectionSpec() { _probability = 1.0; } ARI_FLAG _flag; // UNIRND double _probability; // GP1TO1

int _gpSrcX, _gpDestX, _gpRatioX, _gpRatioY; };

ARI_WGROUP_TEMPLATE

class ARI_WGroup: public ARI_3DObject {

public:

ARI_WGroup() AddFlag(ARI_3DO_FLAG_RENDER ARI_3DO_FLAG_SETINPUT

|ARI_3DO_FLAG_UPDATE); FirstW();}

void RemoveAll() {_wList.RemoveAll(); }

(5)

ARI_W_QUAL * GetAt(unsigned int index) { return _wList[index]; } bool Remove(ARI_W_QUAL *pW);

bool Remove(unsigned int index) {return Remove(GetAt(index)); }

void Dispose2D(unsigned int xSize);

bool AddInputFrom(ARI_W_QUAL* pW, CONNSPEC * pConnectionSpec); bool AddInputFrom(ARI_WGROUP_QUAL* pWG, CONNSPEC * pConnectionSpec, ARI_ProjectionSpec * pProjectionSpec);

bool RemoveInputFrom(ARI_W_QUAL* pW);

bool RemoveInputFrom(ARI_WGROUP_QUAL* pWG, ARI_ProjectionSpec * pProjectionSpec);

void SetOutput(OUTDATA output); // virtuali

void Update(double dt); void SetInput();

void Render();

unsigned int CountW() { return _wList.Count(); }

void FirstW() { _itW = _wList.First(); }

void NextW() { _itW++; }

bool EndW() { return _itW == _wList.End(); }

ARI_W_QUAL* GetW() { return (*_itW); }

private: ARI_WGroup_WList _wList; ARI_WGroup_WList::Iterator _itW; }; #include <ARI_WGroup.inl> #endif ARI_3DWorld.h #ifndef __ARI_3D_WORLD__ #define __ARI_3D_WORLD__ #include <ARI_FastDynamicArray.h> #include <ARI_3DObject.h>

#define ARI_3DWorld_ObjectList ARI_FastDynamicArray<ARI_3DObject*>

class ARI_3DWorld {

public:

ARI_3DObject * GetAt(unsigned int index) { return

(6)

bool AddObject(ARI_3DObject *pObject); bool RemoveObject(ARI_3DObject *pObject); void Render();

void SetInput();

void Update(double dt);

unsigned int CountObject() { return _objectList.Count(); }

void FirstObject() { _itO = _objectList.First(); }

void NextObject() { _itO++; }

bool EndObject() { return _itO == _objectList.End(); }

ARI_3DObject* GetObject() { return (*_itO); }

private: ARI_3DWorld_ObjectList _objectList; ARI_3DWorld_ObjectList::Iterator _itO; }; #endif ARI_3DWorld.cpp #include "stdafx.h" #include <ARI_3DWorld.h> #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

bool ARI_3DWorld::AddObject(ARI_3DObject *pObject) {

_objectList.Add(pObject);

return true;

}

bool ARI_3DWorld::RemoveObject(ARI_3DObject *pObject) { ARI_3DWorld_ObjectList::Iterator it = _objectList.Find(pObject); if(it == _objectList.End()) return false; _objectList.Remove(it); return true; } void ARI_3DWorld::Render() { ARI_FLAG f; for(ARI_3DWorld_ObjectList::Iterator it = _objectList.First(); it != _objectList.End(); it++) { f = (*it)->GetFlags(); if(ARI_FLAG_ISSET(f,ARI_3DO_FLAG_RENDER))

(7)

(*it)->Render(); } } void ARI_3DWorld::SetInput() { ARI_FLAG f; for(ARI_3DWorld_ObjectList::Iterator it = _objectList.First(); it != _objectList.End(); it++) { f = (*it)->GetFlags(); if(ARI_FLAG_ISSET(f,ARI_3DO_FLAG_SETINPUT)) (*it)->SetInput(); } } void ARI_3DWorld::Update(double dt) { ARI_FLAG f; for(ARI_3DWorld_ObjectList::Iterator it = _objectList.First(); it != _objectList.End(); it++) { f = (*it)->GetFlags(); if(ARI_FLAG_ISSET(f,ARI_3DO_FLAG_UPDATE)) (*it)->Update(dt); } } ARI_Array.h #ifndef __ARI_ARRAY__ #define __ARI_ARRAY__

#define ARI_ARRAY_TEMPLATE template<class DATA>

#define ARI_ARRAY_QUAL ARI_Array<DATA>

ARI_ARRAY_TEMPLATE class ARI_Array {

public:

ARI_Array() { _buffer = NULL; _count = 0; }

~ARI_Array() { DeleteBuffer(); }

unsigned int Count() { return _count; }

DATA GetAt(unsigned int index) { return _buffer[index]; }

void SetAt(unsigned int index, DATA data) { _buffer[index] = data;

}

void NewBuffer(unsigned int count);

void QuickSort();

private:

void DeleteBuffer() { if(_buffer) { delete[] _buffer; _buffer =

NULL; _count = 0; } }

void _QuickSort(DATA * numbers, int left, int right);

DATA * _buffer;

(8)

};

#include <ARI_Array.inl> #endif

ARI_Array.inl

ARI_ARRAY_TEMPLATE void ARI_ARRAY_QUAL::NewBuffer(unsigned int count) {

if(count != _count) {

_count = count;

DeleteBuffer();

_buffer = new DATA [_count]; }

}

ARI_ARRAY_TEMPLATE void ARI_ARRAY_QUAL::QuickSort() { _QuickSort(_buffer, 0, _count - 1); /* for(int i=0;i<_count;i++) { TRACE("%f\n",_buffer[i]); }*/ }

ARI_ARRAY_TEMPLATE void ARI_ARRAY_QUAL::_QuickSort(DATA * numbers, int left, int right)

{

int l_hold, r_hold;

DATA pivot;

l_hold = left; r_hold = right;

pivot = numbers[left];

while (left < right) {

while ((numbers[right] >= pivot) && (left < right)) right--; if (left != right) { numbers[left] = numbers[right]; left++; }

while ((numbers[left] <= pivot) && (left < right)) left++; if (left != right) { numbers[right] = numbers[left]; right--; } } numbers[left] = pivot; pivot = left; left = l_hold; right = r_hold; if (left < pivot)

_QuickSort(numbers, left, (int)pivot-1);

if (right > pivot)

_QuickSort(numbers, (int)pivot+1, right);

(9)

ARI_FileSensorDriver.h #ifndef __ARI_FILE_SENSORDRIVER__ #define __ARI_FILE_SENSORDRIVER__ #include <TabData.h> #include <Urn.h> #include <ARI_SensorDriver.h> #include <ARI_Matrix.h>

class ARI_FileSensorDriver: public ARI_SensorDriver {

public:

bool Init(

const CString & fileName,

unsigned int numFeatures,

unsigned int numClasses,

unsigned int featuresStartColIndex = 0,

unsigned int featuresStartRowIndex = 0,

double featuresOffset = 0.0,

double featuresScale = 1.0 );

void Update(double dt);

unsigned int GetEpoch() { return _epoch; }

unsigned int GetDeltaEpoch() { unsigned int de = _epoch - _oldEpoch; _oldEpoch = _epoch; return de; }

private:

unsigned int _epoch, _oldEpoch;

ARI_Matrix _matrix; CUrn<int> _urn; }; #endif ARI_FileSensorDriver.cpp #include "stdafx.h" #include <ARI_FileSensorDriver.h> #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

bool ARI_FileSensorDriver::Init(const CString & fileName, unsigned int numFeatures,

unsigned int numClasses,

unsigned int featuresStartColIndex,

unsigned int featuresStartRowIndex,

double featuresOffset, double featuresScale) { InitDriver("ARI_FileSensorDriver", numFeatures+numClasses); _epoch = 0; _oldEpoch = 0; TabData data; if(!data.FromFile(fileName)) return false;

(10)

int cols = numFeatures+numClasses;

int rows = data.Rows() - featuresStartRowIndex; int x,y;

for(y = 0; y<rows; y++) _urn.Add(y); _matrix.Init(cols,rows); double value;

for(y=0; y<rows; y++)

for(x=0;x<cols;x++) {

if(x < numFeatures)

value =

(data.ReadFloat(featuresStartColIndex+x,featuresStartRowIndex +y) - featuresOffset) / featuresScale;

else value = data.ReadFloat(featuresStartColIndex+x,featuresStartRow Index+y); _matrix.SetAt(x,y,value); } return true; } void ARI_FileSensorDriver::Update(double dt) { if(!IsRegistered()) return; if(!_urn.Count()) { _urn.UndoAll(); _epoch++; // ARI_Log1("Epoch: %u",_epoch); } int y = _urn.DrawingOfLots(); // int y = _urn.Cheat(0);

for(unsigned int i=0;i<_count;i++)

if(_pIFNeurons[i]) _pIFNeurons[i]->SetOutput(_matrix.GetAt(i,y)); } ARI_GLUtils.h #ifndef __ARI_GL_UTILS__ #define __ARI_GL_UTILS__ #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h> #include <ARI_Vector3.h>

void ARI_GLDrawPyramid(float scaleX, float scaleY, float scaleZ); void ARI_GLDrawCube(float scaleX, float scaleY, float scaleZ); float ARI_GLViewAlign(const ARI_Vector3 & Direction);

(11)

#endif;

ARI_GLUtils.cpp #include "stdafx.h" #include <ARI_GLUtils.h> #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

// Renders a pyramid.

void ARI_GLDrawPyramid(float scaleX, float scaleY, float scaleZ) {

GLfloat x1, y1, z1, x2, y2, z2, xv, yv, zv; x1=z1=-0.5f; y1=0.0f; x2=z2=0.5f; y2=1.0f; xv=zv=0.0f; yv=1.0f; glPushMatrix(); glScalef(scaleX,scaleY,scaleZ); // front (z) glBegin(GL_POLYGON); glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f(xv, yv, zv); glVertex3f(x1, y1, z2); glVertex3f(x2, y1, z2); glEnd(); // rear (-z) glBegin(GL_POLYGON); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f(xv, yv, zv); glVertex3f(x2, y1, z1); glVertex3f(x1, y1, z1); glEnd(); // left (-x) glBegin(GL_POLYGON); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(xv, yv, zv); glVertex3f(x1, y1, z1); glVertex3f(x1, y1, z2); glEnd(); // right (x) glBegin(GL_POLYGON); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f(xv, yv, zv); glVertex3f(x2, y1, z2); glVertex3f(x2, y1, z1); glEnd(); // down (-y) glBegin(GL_POLYGON); glNormal3f(0.0f, -1.0f, 0.0f);

(12)

glVertex3f(x1, y1, z1); glVertex3f(x2, y1, z1); glVertex3f(x2, y1, z2); glVertex3f(x1, y1, z2); glEnd(); glPopMatrix(); } // Renders a cube.

void ARI_GLDrawCube(float scaleX, float scaleY, float scaleZ) {

GLfloat x1, y1, z1, x2, y2, z2; x1=y1=z1=-0.5f; x2=y2=z2=0.5f; glPushMatrix(); glScalef(scaleX,scaleY,scaleZ); glBegin(GL_POLYGON); // front (z) glNormal3f(0.0f, 0.0f, 1.0f); glVertex3f(x2, y2, z2); glVertex3f(x1, y2, z2); glVertex3f(x1, y1, z2); glVertex3f(x2, y1, z2); glEnd(); // rear (-z) glBegin(GL_POLYGON); glNormal3f(0.0f, 0.0f, -1.0f); glVertex3f(x2, y2, z1); glVertex3f(x2, y1, z1); glVertex3f(x1, y1, z1); glVertex3f(x1, y2, z1); glEnd(); // left (-x) glBegin(GL_POLYGON); glNormal3f(-1.0f, 0.0f, 0.0f); glVertex3f(x1, y2, z2); glVertex3f(x1, y2, z1); glVertex3f(x1, y1, z1); glVertex3f(x1, y1, z2); glEnd(); // right (x) glBegin(GL_POLYGON); glNormal3f(1.0f, 0.0f, 0.0f); glVertex3f(x2, y2, z2); glVertex3f(x2, y1, z2); glVertex3f(x2, y1, z1); glVertex3f(x2, y2, z1); glEnd(); // up (y) glBegin(GL_POLYGON); glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f(x1, y2, z1); glVertex3f(x1, y2, z2); glVertex3f(x2, y2, z2); glVertex3f(x2, y2, z1); glEnd();

(13)

// down (-y) glBegin(GL_POLYGON); glNormal3f(0.0f, -1.0f, 0.0f); glVertex3f(x1, y1, z1); glVertex3f(x2, y1, z1); glVertex3f(x2, y1, z2); glVertex3f(x1, y1, z2); glEnd(); glPopMatrix(); } // Alignement

float ARI_GLViewAlign(const ARI_Vector3 & Direction) {

float DirectionMag, CrossMag, Angle, Vy; DirectionMag = Direction.Magnitude(); if(!DirectionMag) return 0.0; if(Direction.y < 0.0f) Vy = 1.0f; else Vy = -1.0f; ARI_Vector3 RotationAxis = Direction.Cross(ARI_Vector3(0.0f,Vy,0.0f)); CrossMag = RotationAxis.Magnitude(); if(CrossMag) Angle = ((float)asin(CrossMag/DirectionMag))*180.0f/3.14f; else Angle = 0.0f; if(Vy > 0.0f) Angle -= 180.0f; //pi:Angle=180:x

glRotatef(Angle, RotationAxis.x, RotationAxis.y, RotationAxis.z);

return DirectionMag;

}

// Color

void ARI_GLDrawColor(double data) {

// GLfloat color = (GLfloat)data*0.3+0.05;

// glColor3f(color,0.0f,0.0f); if(data < 0.3) glColor3f((GLfloat)data,0.0f,0.0f); else if(data < 0.7) glColor3f(0.2f,(GLfloat)data-0.3f,0.0f); else glColor3f(0.0f,0.2f,(GLfloat)data-0.7f); } ARI_WGroup.inl

ARI_WGROUP_TEMPLATE void ARI_WGROUP_QUAL::SetOutput(OUTDATA output) {

ARI_WGroup_WList::Iterator it;

for(it = _wList.First(); it != _wList.End(); it++) {

(*it)->SetOutput(output); }

(14)

ARI_WGROUP_TEMPLATE void ARI_WGROUP_QUAL::Dispose2D(unsigned int xSize) { float coeff = 1.8f; float xS = (float)xSize; float yS = ((float)_wList.Count()) / xS; float x,y;

ARI_Vector3 radius = GetRadius(); float xSpacing = 0.0f; if(xS) xSpacing = (radius.x*2.0f)/xS; float ySpacing = 0.0f; if(yS) ySpacing = (radius.y*2.0f)/yS;

ARI_Vector3 pos, position = GetPosition();

pos.z = position.z;

x = 0.0f; y = 0.0f;

ARI_WGroup_WList::Iterator it;

for(it = _wList.First(); it != _wList.End(); it++) {

pos.x = position.x - xSpacing * ( -0.5f + xS / 2.0f - (x) ); pos.y = position.y - ySpacing * ( 0.5f + yS / 2.0f - (yS-y) ); (*it)->SetPosition(pos); (*it)->SetRadius(ARI_Vector3(coeff*radius.x/xS,coeff*radius.y/yS,coeff*radius. z)); x = x + 1.0f; if(x == xS) { x = 0.0f; y = y + 1.0f; } } }

ARI_WGROUP_TEMPLATE void ARI_WGROUP_QUAL::Update(double dt) {

ARI_FLAG f;

ARI_WGroup_WList::Iterator it;

for(it = _wList.First(); it != _wList.End(); it++) { f = (*it)->GetFlags(); if(ARI_FLAG_ISSET(f,ARI_3DO_FLAG_UPDATE)) (*it)->Update(dt); } }

ARI_WGROUP_TEMPLATE void ARI_WGROUP_QUAL::Render() {

ARI_FLAG f;

ARI_WGroup_WList::Iterator it;

for(it = _wList.First(); it != _wList.End(); it++) { f = (*it)->GetFlags(); if(ARI_FLAG_ISSET(f,ARI_3DO_FLAG_RENDER)) (*it)->Render(); } }

(15)

ARI_W_TEMPLATE void ARI_WGROUP_QUAL::SetInput() {

ARI_FLAG f;

ARI_WGroup_WList::Iterator it;

for(it = _wList.First(); it != _wList.End(); it++) { f = (*it)->GetFlags(); if(ARI_FLAG_ISSET(f,ARI_3DO_FLAG_SETINPUT)) (*it)->SetInput(); } } // AddInputFrom: // // PW_1 ---> THIS_GROUP

// pW connects output to all W of this group. //

ARI_WGROUP_TEMPLATE bool ARI_WGROUP_QUAL::AddInputFrom(ARI_W_QUAL* pW, CONNSPEC * pConnectionSpec)

{

ARI_WGroup_WList::Iterator it;

for(it = _wList.First(); it != _wList.End(); it++)

(*it)->AddInputFrom(pW, pConnectionSpec);

return true;

}

Di seguito sono riportate le funzioni che abbiamo utilizzato per tutti tipi possibili di

proiezioni nei collegamenti delle nostre mappe ippocampale.

ARI_WGROUP_TEMPLATE bool ARI_WGROUP_QUAL::AddInputFrom(ARI_WGROUP_QUAL* pWG, CONNSPEC * pConnectionSpec, ARI_ProjectionSpec * pProjectionSpec) {

if(ARI_FLAG_ISSET(pProjectionSpec->_flag,ARI_PROJECTION_FLAG_NTON)) {

ARI_WGroup_WList::Iterator itOther;

for(itOther = >_wList.First(); itOther != pWG->_wList.End(); itOther++) this->AddInputFrom(*itOther, pConnectionSpec); } if(ARI_FLAG_ISSET(pProjectionSpec->_flag,ARI_PROJECTION_FLAG_1TO1)) { ARI_Assert(_wList.Count() >= pWG->_wList.Count(),"ARI_WGROUP_QUAL::AddInputFrom - dimension mismatch"); ARI_WGroup_WList::Iterator it = _wList.First(); ARI_WGroup_WList::Iterator itOther;

for(itOther = >_wList.First(); itOther != pWG->_wList.End(); itOther++) { (*it)->AddInputFrom(*itOther, pConnectionSpec); it++; } } //

(16)

// if(ARI_FLAG_ISSET(pProjectionSpec->_flag,ARI_PROJECTION_FLAG_UNIRNDTON)) { ARI_WGroup_WList::Iterator it = _wList.First(); ARI_W_QUAL * pWSrc;

unsigned int nSrc = pWG->CountW();

unsigned int nConnPerWDest = (unsigned int)(pProjectionSpec->_probability * nSrc);

CUrn<unsigned int> urn;

unsigned int i,k;

for(i=0;i<nSrc;i++) urn.Add(i);

// *it è la W ricevente

for(it = _wList.First(); it != _wList.End(); it++) {

for(i=0; i<nConnPerWDest; i++)

{ k = urn.DrawingOfLots(); pWSrc = pWG->GetAt(k); (*it)->AddInputFrom(pWSrc, pConnectionSpec); } urn.UndoAll(); } } //

// ognuno dei pWG connesso con nConnPerWSrc di thisGroup // if(ARI_FLAG_ISSET(pProjectionSpec->_flag,ARI_PROJECTION_FLAG_NTOUNIRND)) { ARI_WGroup_WList::Iterator it = _wList.First(); ARI_W_QUAL * pWDest;

unsigned int nDest = CountW();

unsigned int nConnPerWSrc = (unsigned int)(pProjectionSpec->_probability * nDest);

CUrn<unsigned int> urn;

unsigned int i,k;

for(i=0;i<nDest;i++) urn.Add(i);

// *it è la W ricevente

for(it = pWG->_wList.First(); it != pWG->_wList.End(); it++) {

for(i=0; i<nConnPerWSrc; i++)

{ k = urn.DrawingOfLots(); pWDest = GetAt(k); pWDest->AddInputFrom((*it), pConnectionSpec); } urn.UndoAll(); } } if(ARI_FLAG_ISSET(pProjectionSpec->_flag,ARI_PROJECTION_FLAG_GP1TO1)) { int srcX = pProjectionSpec->_gpSrcX;

(17)

int srcY = pWG->CountW() / srcX;

int destX = pProjectionSpec->_gpDestX; int destY = this->CountW() / destX;

int stepSrcX = srcX / pProjectionSpec->_gpRatioX; int stepSrcY = srcY / pProjectionSpec->_gpRatioY; int stepDestX = destX / pProjectionSpec->_gpRatioX; int stepDestY = destY / pProjectionSpec->_gpRatioY; ARI_W_QUAL * pWDest, * pWSrc;

int nY = pProjectionSpec->_gpRatioY; int nX = pProjectionSpec->_gpRatioX; for(int zY = 0; zY < nY; zY++)

for(int zX = 0; zX < nX; zX++) {

for(int dY = 0; dY < stepDestY; dY++)

for(int dX = 0; dX < stepDestX; dX++)

{

pWDest =

this->GetAt(zY*destX*stepDestY + zX * stepDestX + dY * destX + dX);

for(int sY = 0; sY < stepSrcY; sY++)

for(int sX = 0; sX < stepSrcX; sX++) { pWSrc = pWG->GetAt(zY*srcX*stepSrcY + zX * stepSrcX + sY * srcX + sX); pWDest->AddInputFrom(pWSrc, pConnectionSpec); } } } } return true; } // AddOutputTo: // // THIS_GROUP ---> PW_1

// All W of this group connect output to pW . //

ARI_WGROUP_TEMPLATE bool ARI_WGROUP_QUAL::AddOutputTo(ARI_W_QUAL* pW, CONNSPEC * pConnectionSpec)

{

ARI_WGroup_WList::Iterator it;

for(it = _wList.First(); it != _wList.End(); it++)

(*it)->AddOutputTo(pW, pConnectionSpec); return true; } // AddOutputTo: // // THIS_GROUP ---> PWG_GROUP

// All W of this group connect output to all W of pWG group. //

ARI_WGROUP_TEMPLATE bool ARI_WGROUP_QUAL::AddOutputTo(ARI_WGROUP_QUAL* pWG, CONNSPEC * pConnectionSpec, ARI_ProjectionSpec * pProjectionSpec) {

return pWG->AddInputFrom(this, pConnectionSpec, pProjectionSpec); }

(18)

// RemoveOutputTo: //

// THIS_GROUP -X-> PW_1

// All W of this group disconnect output from pW . //

ARI_WGROUP_TEMPLATE bool ARI_WGROUP_QUAL::RemoveOutputTo(ARI_W_QUAL* pW) {

ARI_WGroup_WList::Iterator it;

for(it = _wList.First(); it != _wList.End(); it++) (*it)->RemoveOutputTo(pW); return true; } // RemoveOutputTo: // // THIS_GROUP -X-> PWG_GROUP

// All W of this group disconnect output from all W of pWG group. //

ARI_WGROUP_TEMPLATE bool

ARI_WGROUP_QUAL::RemoveOutputTo(ARI_WGROUP_QUAL* pWG, ARI_ProjectionSpec * pProjectionSpec)

{

return pWG->RemoveInputFrom(this, pProjectionSpec); }

// RemoveInputFrom: //

// PW_1 -X-> THIS_GROUP

// pW disconnects output from all W of this group. //

ARI_WGROUP_TEMPLATE bool ARI_WGROUP_QUAL::RemoveInputFrom(ARI_W_QUAL* pW)

{

ARI_WGroup_WList::Iterator it;

for(it = _wList.First(); it != _wList.End(); it++) (*it)->RemoveInputFrom(pW); return true; } // RemoveInputFrom: // // PWG_GROUP -X-> THIS_GROUP

// All W of pWG group disconnect output from all W of this group. // ARI_WGROUP_TEMPLATE bool ARI_WGROUP_QUAL::RemoveInputFrom(ARI_WGROUP_QUAL* pWG, ARI_ProjectionSpec * pProjectionSpec) { if(ARI_FLAG_ISSET(pProjectionSpec->_flag,ARI_PROJECTION_FLAG_NTON)) { ARI_WGroup_WList::Iterator itOther;

for(itOther = >_wList.First(); itOther != pWG->_wList.End(); itOther++) this->RemoveInputFrom(*itOther); } if(ARI_FLAG_ISSET(pProjectionSpec->_flag,ARI_PROJECTION_FLAG_1TO1)) { ARI_Assert(_wList.Count() >= pWG->_wList.Count(),"ARI_WGROUP_QUAL::AddInputFrom - dimension mismatch");

(19)

ARI_WGroup_WList::Iterator it = _wList.First();

ARI_WGroup_WList::Iterator itOther;

for(itOther = >_wList.First(); itOther != pWG->_wList.End(); itOther++) { (*it)->RemoveInputFrom(*itOther); it++; } } return true; }

Ora riportiamo i file che più propriamente eseguono le operazioni proprie del modello

Leabra

ARI_LeabraNeuron.h #ifndef __ARI_LEABRANEURON__ #define __ARI_LEABRANEURON__ #include <ARI_W.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glaux.h> #include <ARI_Vector3.h> #include <ARI_Value.h> #include <math.h>

struct ARI_LeabraNeuronConnectionSpec: public ARI_WConnectionSpec {

ARI_LeabraNeuronConnectionSpec() { InitSpec(); }

void InitSpec(double alpha = 1.0, double w_gain = 1.0, double w_off = 1.0, unsigned int id = 0, unsigned int n = 1)

{ _alpha = alpha; _w_gain = w_gain; _w_off = w_off; _id = id; _n = n; }

void InitLearn(double lr0 = 0.1, double lr_decay = 0.0) { _lr = lr0; _lr0 = lr0; _lr_decay = lr_decay; } ARI_Value _weight; bool Init() { return _weight.Init(); }

double _alpha, _w_gain, _w_off, _lr, _lr0, _lr_decay; unsigned int _id, _n;

(20)

#define ARI_LeabraNeuronConnection ARI_WConnection<double,

ARI_LeabraNeuronConnectionSpec> class ARI_LeabraNeuron : public ARI_W<double,

ARI_LeabraNeuronConnectionSpec> {

public:

ARI_LeabraNeuron() { _dtNet = 0.7; _g_e_k = 0.0;

_g_e = 0.0; _g_e_star = 0.0; _V_m = 0.15; }

// Render:

void Render();

void SetInput();

double GetGek() { return _g_e_k; }

double GetGeStar() { return _g_e_star; }

double GetGe() { return _g_e; }

double GetVm() { return _V_m; }

void SetVm(double V_m) { _V_m = V_m; }

void SetGe(double g_e) { _g_e = g_e; }

private:

double Process(double dt);

double _dtNet;

double _g_e_k, _g_e_star;

double _g_e; double _V_m; }; #endif ARI_LeabraNeuron.cpp #include "stdafx.h" #include <ARI_LeabraNeuron.h> #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

double ARI_LeabraNeuron::Process(double dt) {

double g_e_k_bias, beta = 0.0000, N; ARI_LeabraNeuronConnection * pC; N = CountWCInput();

(21)

for(FirstWCInput(); !EndWCInput(); NextWCInput()) {

pC = (ARI_LeabraNeuronConnection *)GetWCInput(); _g_e_k += (pC->_output * pC-> _connectionSpec. _weight._value) / (>_connectionSpec._n * pC->_connectionSpec._alpha);

} if(N) {

g_e_k_bias = _g_e_k + beta / N;

_g_e = (1.0 - _dtNet) * _g_e + _dtNet * g_e_k_bias; _g_e_star = _g_e - _dtNet * ( beta / N );

} return GetOutput(); } void ARI_LeabraNeuron::SetInput() { ARI_LeabraNeuronConnection * pC;

for(FirstWCInput(); !EndWCInput(); NextWCInput())

{ pC = (ARI_LeabraNeuronConnection *)GetWCInput(); pC->_output = pC->_pWSrc->GetOutput(); pC->_connectionSpec._alpha = 1.0; } } void ARI_LeabraNeuron::Render() {

ARI_Vector3 position = GetPosition(); ARI_Vector3 radius = GetRadius(); glPushMatrix();

glTranslatef(position.x, position.y, position.z);

glEnable(GL_COLOR_MATERIAL) ; glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); float y = (float)GetOutput(); ARI_GLDrawColor(y); if(y==0.0f) y = 0.05f; ARI_GLDrawCube(y*radius.x,y*radius.y,radius.z); glPopMatrix(); #ifndef ARI_GLCONN_DONT_DRAW ARI_Vector3 startPosition; ARI_LeabraNeuronConnection * pC;

for(FirstWCInput(); !EndWCInput(); NextWCInput())

{

pC = (ARI_LeabraNeuronConnection *)GetWCInput();

//if((*itI)!=this) ??

ARI_GLDrawColor(pC->_connectionSpec._weight._value);

(22)

glPushMatrix();

glTranslatef( startPosition.x, startPosition.y, startPosition.z);

float Mag = ARI_GLViewAlign(position - startPosition); ARI_GLDrawPyramid( (float)(pC->_connectionSpec._weight._value*radius.x/5.0), Mag, (float)(pC->_connectionSpec._weight._value*radius.z/5.0) ); glPopMatrix(); } #endif glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHT0); glDisable(GL_LIGHTING); } ARI_LeabraNeuronGroup.h #ifndef __ARI_LEABRANEURON_GROUP__ #define __ARI_LEABRANEURON_GROUP__ #include <ARI_WGroup.h> #include <ARI_LeabraNeuron.h> #include <ARI_Macro.h> #include <ARI_Array.h> #include <stdlib.h> class ARI_LeabraNeuronGroup : publicARI_WGroup<double,ARI_LeabraNeuronConnectionSpec> { public:

ARI_LeabraNeuronGroup() { _g_e_bar = 1.00; _g_i_bar =

1.00; _g_l_bar = 0.10; _E_e = 1.00; _E_i = 0.15; _E_l = 0.15; _teta = 0.25; _dtVm = 0.2; _gamma = 600; _g_l = 1.00; } void Update(double dt);

void UpdateWeights(double dt, bool contrastEnhancement = true); void Reset();

void Init(unsigned int k, double q) { _k = k; _q = q; }

void InitLearn(unsigned int count, unsigned int * id, double * lr0, double * lr_decay);

private:

ARI_Array<double> _g_i_teta;

double _g_e_bar , _g_i_bar, _g_l_bar, _E_e, _E_i, _E_l, _teta, _q, _dtVm, _g_l;

unsigned int _k, _gamma; }; #endif ARI_LeabraNeuronGroup.cpp #include "stdafx.h" #include <ARI_LeabraNeuronGroup.h> #ifdef _DEBUG

(23)

#undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

void ARI_LeabraNeuronGroup::Update(double dt) {

ARI_LeabraNeuron * pN; double g_i_teta, g_i; int i = 0, n = CountW(); _g_i_teta.NewBuffer(n);

for(FirstW(); !EndW(); NextW())

{

pN = (ARI_LeabraNeuron*)(GetW());

pN->Update(dt);

g_i_teta = (pN->GetGeStar() * _g_e_bar * (_E_e - _teta) + _g_l_bar * (_E_l - _teta)) / (_teta - _E_i);

_g_i_teta.SetAt(i, g_i_teta);

i++; }

// ordino di _g_i_teta: dal più piccolo al più grande _g_i_teta.QuickSort();

// uso il k-esimo e (k+1)-esimo più grande, con il (k+1)-esimo che //ha attivazione minore del k-esimo, dunque parto dal basso

g_i = _g_i_teta.GetAt(n - _k - 1) + _q * ( _g_i_teta.GetAt(n - _k) - _g_i_teta.GetAt(n - _k - 1));

double V_m, tmp, y;

for(FirstW(); !EndW(); NextW()) {

pN = (ARI_LeabraNeuron*)(GetW()); V_m = pN->GetVm();

tmp = _gamma * ARI_ZERO_THRESHOLD(V_m - _teta);

pN->SetVm( V_m + _dtVm * (pN->GetGe() * _g_e_bar * (_E_e - V_m) + g_i * _g_i_bar * (_E_i - V_m) + _g_l_bar * (_E_l - V_m)) ); y = tmp / (tmp + 1.00); pN->SetOutput(y); } } void ARI_LeabraNeuronGroup::UpdateWeights(float dt) { ARI_LeabraNeuron * pN; ARI_LeabraNeuronConnection * pC; double w, x, y;

(24)

{

pN = (ARI_LeabraNeuron*)(GetW());

y = pN->GetOutput();

// aggiorno i pesi

for(pN->FirstWCInput(); !pN->EndWCInput(); pN->NextWCInput())

{

pC = (ARI_LeabraNeuronConnection*) pN->GetWCInput();

w = pC->_connectionSpec._weight._value;

x = pC->_output;

w += pC->_connectionSpec._lr * y * (x - w); // filtriamo il peso con contrast enhancement

w = 1.0/(1.0 + pow( pC->_connectionSpec._w_off*w/(1.0-w), -pC->_connectionSpec._w_gain)); pC->_connectionSpec._weight._value = w; pC->_connectionSpec._lr -= pC->_connectionSpec._lr0 * pC->_connectionSpec._lr_decay * dt; } } }

void ARI_LeabraNeuronGroup::InitLearn(unsigned int count, unsigned int * id, double * lr0, double * lr_decay) {

ARI_LeabraNeuron * pN;

ARI_LeabraNeuronConnection * pC; unsigned int i;

for(FirstW(); !EndW(); NextW())

{

pN = (ARI_LeabraNeuron*)(GetW());

for(pN->FirstWCInput(); !pN->EndWCInput(); pN->NextWCInput())

{ pC = (ARI_LeabraNeuronConnection*) pN->GetWCInput(); for(i=0;i<count;i++) { if(pC->_connectionSpec._id == id[i]) pC>_connectionSpec.InitLearn(lr0[i],lr_decay[i]); } } } } void ARI_LeabraNeuronGroup::Reset() { ARI_LeabraNeuron * pN;

for(FirstW(); !EndW(); NextW())

{ pN = (ARI_LeabraNeuron*)(GetW()); pN->SetVm(0.15); pN->SetGe(0.0); pN->SetOutput(0.0); } }

(25)

ARI_Macro.h

#ifndef __ARI_MACRO__ #define __ARI_MACRO__

static int __mem=0,__arr=0; // memory

#define ARI_DeleteMem(Obj) delete(Obj);__mem--

#define ARI_DeleteArray(Obj) delete[](Obj);__arr--

#define ARI_DeleteMemZ(Obj) {ARI_DeleteMem((Obj));(Obj)=NULL;}

#define ARI_DeleteArrayZ(Obj) {ARI_DeleteArray((Obj));(Obj)=NULL;}

#define ARI_DeleteMemEx(Obj) {if((Obj))ARI_DeleteMemZ((Obj));}

#define ARI_DeleteArrayEx(Obj) {if((Obj))ARI_DeleteArrayZ((Obj));}

#define ARI_NewMem(Type) new Type;__mem++

#define ARI_NewArray(Type, Count) new Type[(Count)];__arr++

// flags

#define ARI_FLAG unsigned int

#define ARI_FLAG_MASK ((1<<(sizeof(ARI_FLAG)*8))-1)

#define ARI_FLAG_NULL 0

#define ARI_FLAG_SET(af,f) (af)=(f)

#define ARI_FLAG_ISSET(af,f) ((af)&(f))==(f)

#define ARI_FLAG_ADD(af,f) (af)|=(f)

#define ARI_FLAG_REM(af,f) (af)&=(ARI_FLAG_MASK-(f))

// utils

// allow as function names for valarray :-) #undef min

#undef max

// min-max macros

#define MIN(A,B) ((A) < (B) ? (A) : (B))

#define MAX(A,B) ((A) > (B) ? (A) : (B))

// rand

#define ARI_INIT_RAND srand( (unsigned)time( NULL ) )

#define ARI_RAND_FLOAT(minValue,maxValue) ( (minValue) + ( ( (

(double)rand() )*((maxValue)-(minValue))/RAND_MAX ) ) ) #define ARI_RAND_INT(minValue,maxValue) (int)(ARI_RAND_FLOAT((minValue),(maxValue)+0.999)) // rendering //#define ARI_GLNEURON_DRAW_FAST #define ARI_GLCONN_DONT_DRAW // zero threshold

#define ARI_ZERO_THRESHOLD(X) MAX((X),0) // win32 debug interface

#include <afxwin.h>

#define ARI_String CString

// dialogs

(26)

#define ARI_WAR(msg) ARI_DLG(msg,MB_ICONEXCLAMATION|MB_OK)

#define ARI_ERR(msg) ARI_DLG(msg,MB_ICONERROR|MB_OK)

#define ARI_OUT(msg) ARI_DLG(msg,MB_ICONINFORMATION|MB_OK)

#define ARI_ASK(msg) (ARI_DLG(msg,MB_ICONQUESTION|MB_YESNO)==IDYES)

#define ARI_CHO(msg) ARI_DLG(msg,MB_ICONINFORMATION|MB_YESNOCANCEL)

#define ARI_SLE(msg) \ { \

CTime curTime = CTime::GetCurrentTime(); \

CString CurrentTime = curTime.Format( "%H:%M:%S, %B %d, %Y" ); \

CString lastError = CurrentTime + ", " + msg; \

ARI_TRACE0(lastError); \

} // log(TRACE) & assert(DIALOG) #ifdef _DEBUG

// out for matrix

#define TRACEMAT(m) {for(int y=1;y<=(m).rownum();y++){CString

add,row("\n[");for(int

x=1;x<=(m).colnum();x++){add.Format("\t%f", (m)(y,x));row+=add;}row+="\t]";TRACE(row);} TRACE("\n");}

// Log

#define ARI_Log(msg) ARI_Log0(msg)

#define ARI_Log0(msg) ARI_SLE(msg)

#define ARI_Log1(msg,p1) {ARI_String _msg;

_msg.Format(msg,p1); ARI_Log0(_msg); }

#define ARI_Log2(msg,p1,p2) {ARI_String _msg;

_msg.Format(msg,p1,p2); ARI_Log0(_msg); }

#define ARI_Log3(msg,p1,p2,p3) {ARI_String _msg;

_msg.Format(msg,p1,p2,p3); ARI_Log0(_msg); }

// Assert //assert((text)||(!(reason)))

#define ARI_Assert(reason,msg) ARI_Assert0(reason,msg)

#define ARI_Assert0(reason,msg) {if(!(reason)){CString

_msg(msg),_base; _base.Format("ARI Assertion failed in %s at line %u:\r\n\r\n",__FILE__,__L INE__);ARI_WAR(_base+_msg );}}

#define ARI_Assert1(reason,msg,p1) {ARI_String _msg;

_msg.Format(msg,p1); ARI_Assert0(reason,_msg); }

#define ARI_Assert2(reason,msg,p1,p2) {ARI_String _msg;

(27)

ARI_Assert0(reason,_msg); }

#define ARI_Assert3(reason,msg,p1,p2,p3) {ARI_String _msg;

_msg.Format(msg,p1,p2,p3) ;

ARI_Assert0(reason,_msg); }

#else

// out for matrix

#define TRACEMAT // Log #define ARI_Log #define ARI_Log0 #define ARI_Log1 #define ARI_Log2 #define ARI_Log3 // Assert #define ARI_Assert #define ARI_Assert0 #define ARI_Assert1 #define ARI_Assert2 #define ARI_Assert3 #endif #endif

Non resta che includere i due file che compongono il main con la sequenza di operazioni

per lo svolgimento dei processi della nostra simulazione.

MainFrm.h #if !defined(AFX_MAINFRM_H__FDF555C4_C5F4_447D_8D97_2DAC19BA85D1__INCLUDED_) #define AFX_MAINFRM_H__FDF555C4_C5F4_447D_8D97_2DAC19BA85D1__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "ViewDlg.h" #include "ChildView.h"

#define MAIN_APP ((CARIAppApp*)AfxGetApp())

#define MAIN_WND ((CMainFrame*)(MAIN_APP->m_pMainWnd))

#define MAIN_VIEW ((CChildView*)(&(MAIN_WND->m_wndView)))

#include <ARI_3DObject.h> #include <ARI_3DWorld.h> #include <ARI_IFNeuron.h> #include <ARI_IFNeuronGroup.h> #include <ARI_IFKohonen.h> #include <ARI_FileSensorDriver.h> #include <ARI_IFSOM.h> #include <ARI_ChewingSensorDriver.h>

(28)

#include <ARI_LeabraNeuron.h> #include <ARI_LeabraNeuronGroup.h>

#define LEABRA_INPUT_AB_FILE _myDir+"ABAC\\LeabraInputAB.txt" #define LEABRA_INPUT_AC_FILE _myDir+"ABAC\\LeabraInputAC.txt" #define CL 0 #define IX 8 #define IY 18 #define ECINX 8 #define ECINY 18 #define ECOUTX 8 #define ECOUTY 18 #define DGX 25 #define DGY 25 #define CA3X 10 #define CA3Y 24 #define CA1X 16 #define CA1Y 24 #define RX 2 #define RY 6 #define LR 0.1 #define CID_ECIN_CA1 1 #define CID_CA1_ECOUT 2 #define CID_ECIN_DG 3 #define CID_ECIN_ECOUT 4 #define CID_ECOUT_ECIN 5 #define CID_ECIN_CA3 6 #define CID_CA3_CA1 7 #define CID_DG_CA3 8 #define CID_CA3_CA3 9 #define CID_IN_ECIN 10 #define FIRST_STAGE 1 #define SECOND_STAGE 4

class CMainFrame : public CFrameWnd { public: CMainFrame(); protected: DECLARE_DYNAMIC(CMainFrame) // Attributes public: UINT _status; CViewDlg _view; DWORD _frames,_oldTick; CString _myDir;

double _stm_err_off, _stm_err_on;

unsigned int _errorFrame;

(29)

ARI_3DWorld _world; ARI_IFNeuron _input[IX*IY]; ARI_IFNeuronGroup _inputGroup; ARI_LeabraNeuron _ecIn[ECINX*ECINY]; ARI_LeabraNeuronGroup _ecInGroup; ARI_LeabraNeuronGroup _ecInSubGroup[RX*RY]; ARI_LeabraNeuron _dg[DGX*DGY]; ARI_LeabraNeuronGroup _dgGroup; ARI_LeabraNeuron _ca3[CA3X*CA3Y]; ARI_LeabraNeuronGroup _ca3Group; ARI_LeabraNeuron _ca1[CA1X*CA1Y]; ARI_LeabraNeuronGroup _ca1Group; ARI_LeabraNeuronGroup _ca1SubGroup[RX*RY]; ARI_LeabraNeuron _ecOut[ECOUTX*ECOUTY]; ARI_LeabraNeuronGroup _ecOutGroup; ARI_LeabraNeuronGroup _ecOutSubGroup[RX*RY]; ARI_ABACSensorDriver _driverFile; public: // Overrides

// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMainFrame)

virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,

AFX_CMDHANDLERINFO* pHandlerInfo);

//}}AFX_VIRTUAL // Implementation

public:

void LeabraMakeInput(const CString & fileNameAB, const CString & fileNameAC);

void Update();

void Init();

virtual ~CMainFrame();

#ifdef _DEBUG

virtual void AssertValid() const;

virtual void Dump(CDumpContext& dc) const; #endif

protected: // control bar embedded members

CStatusBar m_wndStatusBar;

CToolBar m_wndToolBar; CChildView m_wndView; protected:

//{{AFX_MSG(CMainFrame)

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSetFocus(CWnd *pOldWnd);

afx_msg void On3dView();

afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnTrainingStep();

//}}AFX_MSG

(30)

private:

void LoadECInCA1Weights();

void LoadCA1ECOutWeights();

void GroupToSubGroups(ARI_LeabraNeuronGroup * pGroup, ARI_LeabraNeuronGroup * pSubGroups unsigned int srcX, unsigned int srcY, unsigned int ratioX, unsigned int ratioY); void CalcError();

void LeabraMakeInput(const CString & fileNameAB, const CString & fileNameAC);

void Update();

void Init();

void DisconnectECInCA1();

void ConnectECInCA1();

void SetTrainingAB() { _driverFile.SetTraining();

_driverFile.SetAB(); }

void SetTrainingAC() { _driverFile.SetTraining();

_driverFile.SetAC(); }

void SetTestAB() { _driverFile.SetTest();

_driverFile.SetAB(); }

void SetTestAC() { _driverFile.SetTest();

_driverFile.SetAC(); } void UpdateStatus(); void InitTotalConn(); }; #endif MainFrm.cpp #include "stdafx.h" #include "ARIApp.h" #include "MainFrm.h" #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif // CMainFrame IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() ON_WM_SETFOCUS() ON_COMMAND(IDM_3D_VIEW, On3dView) ON_WM_TIMER() ON_COMMAND(IDM_TRAINING_STEP, OnTrainingStep) //}}AFX_MSG_MAP END_MESSAGE_MAP()

static UINT indicators[] = {

ID_SEPARATOR, // status line indicator ID_INDICATOR_CAPS,

(31)

ID_INDICATOR_SCRL, };

// CMainFrame construction/destruction CMainFrame::CMainFrame()

{

// TODO: add member initialization code here } CMainFrame::~CMainFrame() { } nt CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;

// create a view to occupy the client area of the frame if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,

CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL)) {

TRACE0("Failed to create view window\n");

return -1;

}

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP

| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) || !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

{

TRACE0("Failed to create toolbar\n"); return -1; // fail to create }

if (!m_wndStatusBar.Create(this) ||

!m_wndStatusBar.SetIndicators(indicators,

sizeof(indicators)/sizeof(UINT)))

{

TRACE0("Failed to create status bar\n"); return -1; // fail to create

}

// TODO: Delete these three lines if you don't want the toolbar to // be dockable m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndToolBar); TCHAR dir[1024]; if(GetCurrentDirectory(1024,dir)) _myDir.Format("%s\\",dir); else _myDir.Empty(); MTRACE0(_myDir); Init(); return 0; } BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) { if( !CFrameWnd::PreCreateWindow(cs) ) return FALSE;

(32)

// TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs

cs.dwExStyle &= ~WS_EX_CLIENTEDGE;

cs.lpszClass = AfxRegisterWndClass(0);

return TRUE;

}

// CMainFrame diagnostics #ifdef _DEBUG

void CMainFrame::AssertValid() const {

CFrameWnd::AssertValid(); }

void CMainFrame::Dump(CDumpContext& dc) const {

CFrameWnd::Dump(dc); }

#endif //_DEBUG

// CMainFrame message handlers

void CMainFrame::OnSetFocus(CWnd* pOldWnd) {

// forward focus to the view window m_wndView.SetFocus();

}

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)

{

// let the view have first crack at the command

if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))

return TRUE;

// otherwise, do default handling

return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); }

void CMainFrame::On3dView() {

// TODO: Add your command handler code here _view.ShowWindow(SW_SHOW); } void CMainFrame::Init() { ARI_INIT_RAND; _errorFrame = 0; _stm_err_off = 0.0; _stm_err_on = 0.0; _status = 0; // this->LeabraMakeInput(LEABRA_INPUT_AB_FILE_TRAINING, // LEABRA_INPUT_AC_FILE_TRAINING, LEABRA_INPUT_AB_FILE_TEST, // LEABRA_INPUT_AC_FILE_TEST); // return; // pos e size

(33)

_testGroup.SetPosition(ARI_Vector3(-10.0, 0.0, -5.0)); _testGroup.SetRadius(ARI_Vector3(4.0f,4.0f,0.1f)); _inputGroup.SetPosition(ARI_Vector3(0.0, 0.0, -5.0)); _inputGroup.SetRadius(ARI_Vector3(4.0f,4.0f,0.1f)); _ecInGroup.SetPosition(ARI_Vector3(0.0, 0.0, -10.0)); _ecInGroup.SetRadius(ARI_Vector3(4.0f,4.0f,0.1f)); _ecOutGroup.SetPosition(ARI_Vector3(7.0, 0.0, -15.0)); _ecOutGroup.SetRadius(ARI_Vector3(4.0f,4.0f,0.1f)); _dgGroup.SetPosition(ARI_Vector3(0.0, 0.0, -20.0)); _dgGroup.SetRadius(ARI_Vector3(10.0f,4.0f,0.1f)); _ca3Group.SetPosition(ARI_Vector3(-8.0, 0.0, -25.0)); _ca3Group.SetRadius(ARI_Vector3(4.0f,4.0f,0.1f)); _ca1Group.SetPosition(ARI_Vector3(4.0, 0.0, -30.0)); _ca1Group.SetRadius(ARI_Vector3(7.0f,4.0f,0.1f)); // groups int i; for(i=0;i<IX*IY;i++) { _inputGroup.Add(&(_input[i])); _testGroup.Add(&(_test[i])); } for(i=0;i<ECINX*ECINY;i++) { _ecInGroup.Add(&(_ecIn[i])); } for(i=0;i<ECOUTX*ECOUTY;i++) { _ecOutGroup.Add(&(_ecOut[i])); } for(i=0;i<DGX*DGY;i++) { _dgGroup.Add(&(_dg[i])); } for(i=0;i<CA3X*CA3Y;i++) { _ca3Group.Add(&(_ca3[i])); } for(i=0;i<CA1X*CA1Y;i++) { _ca1Group.Add(&(_ca1[i])); } // connect InitTotalConn(); //InitTrainingConn(); GroupToSubGroups(&_ecInGroup, _ecInSubGroup,ECINX,ECINY,RX,RY); GroupToSubGroups(&_ecOutGroup, _ecOutSubGroup,ECOUTX,ECOUTY,RX,RY); GroupToSubGroups(&_ca1Group, _ca1SubGroup,CA1X,CA1Y,RX,RY);

(34)

InitPreWeights(); // init _inputGroup.Dispose2D(IX); _testGroup.Dispose2D(IX); _ecInGroup.Dispose2D(ECINX); _ecOutGroup.Dispose2D(ECOUTX); _dgGroup.Dispose2D(DGX); _ca3Group.Dispose2D(CA3X); _ca1Group.Dispose2D(CA1X); // register _world.AddObject(&_inputGroup); _world.AddObject(&_testGroup); // _world.AddObject(&_ecInGroup); // _world.AddObject(&_ecOutGroup); _world.AddObject(&_dgGroup); _world.AddObject(&_ca3Group); // _world.AddObject(&_ca1Group); for(i=0;i<RX*RY;i++) { _ecInSubGroup[i].Init(3, 0.25); _ecOutSubGroup[i].Init(3, 0.25); _ca1SubGroup[i].Init(3, 0.25); _world.AddObject(&(_ecInSubGroup[i])); _world.AddObject(&(_ecOutSubGroup[i])); _world.AddObject(&(_ca1SubGroup[i])); } // drivers if(!_driverFile.Init(LEABRA_INPUT_AB_FILE, LEABRA_INPUT_AC_FILE,

IX*9, IX*3, IX*6, CL )) {

ARI_Log("MAIN: _driverFile failed to connect"); } _driverFile.Register(&_inputGroup); _driverFile.Register(&_testGroup); _driverFile.SetTest(); _driverFile.Update(0.0); // stuff _oldTick = GetTickCount(); _frames = 0; _view.Create(IDD_VIEW_DIALOG,this); SetTimer(1,10,NULL); }

void CMainFrame::OnTimer(UINT nIDEvent) {

// TODO: Add your message handler code here and/or call default Update(); CFrameWnd::OnTimer(nIDEvent); } void CMainFrame::Update() { _frames++;

(35)

DWORD dTick = GetTickCount() - _oldTick; float dt = dTick/1000.0f; if(dTick > 1000) { float fps = 1000.0f*((float)_frames)/dTick; CString msg; msg.Format("%.01f fps",fps); this->SetWindowText(msg); _frames = 0; _oldTick += dTick; } // CalcError(); // if(dTick > 1000) // OnTrainingStep(); _world.SetInput(); _world.Update(0.0); if(_status>0) { CalcError(); UpdateStatus(); } _view.Invalidate(FALSE); } void CMainFrame::OnTrainingStep() {

// TODO: Add your command handler code here

double dtEpoch = (double)(_driverFile.GetDeltaEpoch()); _ecInGroup.UpdateWeights(dtEpoch); _ecOutGroup.UpdateWeights(dtEpoch); _dgGroup.UpdateWeights(dtEpoch); _ca3Group.UpdateWeights(dtEpoch); _ca1Group.UpdateWeights(dtEpoch); _ecInGroup.SetOutput(0.0); _ecOutGroup.SetOutput(0.0); _dgGroup.SetOutput(0.0); _ca3Group.SetOutput(0.0); _ca1Group.SetOutput(0.0); _driverFile.Update(0.0); }

void CMainFrame::LeabraMakeInput(const CString & fileNameAB, const

CString & fileNameAC)

{

// context 6 righe // B/C 6 righe // A 6 righe

const int numEsempi = 10; const double act = 0.95;

(36)

int i,j,r,c;

TabData AB[numEsempi], AC[numEsempi]; for(i=0;i<numEsempi;i++) { AB[i].Reset(8); AB[i].PushRow(18); AC[i].Reset(8); AC[i].PushRow(18); } ARI_INIT_RAND; int nc; TD_FLOAT oldValue;

// AB[0] scelto a caso for(r=0;r<18;r++) { for(c=0;c<8;c+=4) { nc = ARI_RAND_INT(0, 3); for(i=0;i<4;i++) { if(i == nc) AB[0].WriteFloat(c+i,r,act); else AB[0].WriteFloat(c+i,r,0.0); } } } AB[0].Dump(); for(j=1;j<numEsempi;j++) {

// le prime 6 righe sono del contesto e la facciamo variare poco for(r=0;r<6;r++) for(c=0;c<8;c++) AB[j].WriteFloat(c,r,0.0); for(r=0;r<6;r++) { for(c=0;c<8;c+=4) { for(i=0;i<4;i++) { oldValue = AB[0].ReadFloat(c+i,r); if(oldValue != 0.0) { nc = ARI_RAND_INT(-1, 1); nc += i; if( nc < 0 ) nc = 0; if( nc > 3) nc = 3; AB[j].WriteFloat(c+nc,r,act); }

(37)

} }

}

// per le altre facciamo come prima for(r=6;r<18;r++) { for(c=0;c<8;c+=4) { nc = ARI_RAND_INT(0, 3); for(i=0;i<4;i++) { if(i == nc) AB[j].WriteFloat(c+i,r,act); else AB[j].WriteFloat(c+i,r,0.0); } } } }

// AC è uguale ad AB tranne per le righe da 9 a 12 dove c'è infatti // C for(j=0;j<numEsempi;j++) { AC[j].CopyFrom(AB[j]); for(r=9;r<12;r++) { for(c=0;c<8;c+=4) { nc = ARI_RAND_INT(0, 3); for(i=0;i<4;i++) { if(i == nc) AC[j].WriteFloat(c+i,r,act); else AC[j].WriteFloat(c+i,r,0.0); } } } }

TabData ABFile(8*18), ACFile(8*18);

for(j=0;j<numEsempi;j++) for(r=0;r<18;r++) for(c=0;c<8;c++) { ABFile.PushFloat(AB[j].ReadFloat(c,r)); ACFile.PushFloat(AC[j].ReadFloat(c,r)); } ABFile.ToFile(fileNameABTraining); ACFile.ToFile(fileNameACTraining); /* for(j=0;j<numEsempi;j++) for(r=9;r<12;r++) for(c=0;c<8;c++) { ABFile.WriteFloat(r*8+c,j,0.0); ACFile.WriteFloat(r*8+c,j,0.0); }

(38)

ABFile.ToFile(fileNameABTest); ACFile.ToFile(fileNameACTest); */ } void CMainFrame::InitTotalConn() {

BOOL totalConn = TRUE; double lr = LR; // connect ARI_LeabraNeuronConnectionSpec c; ARI_ProjectionSpec p; // Input->EC_in p._flag = ARI_PROJECTION_FLAG_1TO1; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.9; c._weight._variance = 0.01; c.InitSpec(2.2, 1.0, 1.0); c.InitLearn(0.0, 0.0); _ecInGroup.AddInputFrom( (ARI_LeabraNeuronGroup*)&_inputGroup,&c,&p); // EC_in->DG p._flag = ARI_PROJECTION_FLAG_UNIRNDTON; p._probability = 0.25; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.5; c._weight._variance = 0.25; c.InitSpec(0.25, 1.0, 1.0); c.InitLearn(0.1, 0.0); if(totalConn) _dgGroup.AddInputFrom(&_ecInGroup,&c,&p, CID_ECIN_DG); // EC_in->EC_out p._flag = ARI_PROJECTION_FLAG_1TO1; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.9; c._weight._variance = 0.01; c.InitSpec(9999999999999999.0, 1.0, 1.0); c.InitLearn(0.0, 0.0); _ecOutGroup.AddInputFrom(&_ecInGroup,&c,&p); // EC_out->EC_in p._flag = ARI_PROJECTION_FLAG_1TO1; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.9; c._weight._variance = 0.01; c.InitSpec(5.5, 1.0, 1.0); c.InitLearn(0.0, 0.0),

(39)

_ecInGroup.AddInputFrom(&_ecOutGroup,&c,&p); // EC_in->CA3 p._flag = ARI_PROJECTION_FLAG_UNIRNDTON; p._probability = 0.25; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.5; c._weight._variance = 0.25; c.InitSpec(20.25, 1.0, 1.0); c.InitLearn(0.1, 0.0); if(totalConn) _ca3Group.AddInputFrom(&_ecInGroup,&c,&p, CID_ECIN_CA3); // EC_in->CA1 ConnectECInCA1(); // CA3->CA1 p._flag = ARI_PROJECTION_FLAG_NTON; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.5; c._weight._variance = 0.25; c.InitSpec(4.66666666666, 1.0, 1.0); c.InitLearn(0.1, 0.0); if(totalConn) _ca1Group.AddInputFrom(&_ca3Group,&c,&p, CID_CA3_CA1); // CA1->EC_out p._flag = ARI_PROJECTION_FLAG_GP1TO1; p._gpDestX = ECOUTX; p._gpSrcX = CA1X; p._gpRatioX = 2; p._gpRatioY = 6; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.9; c._weight._variance = 0.01; c.InitSpec(5.0, 6.0, 1.25, 2); c.InitLearn(0.0, 0.0); _ecOutGroup.AddInputFrom(&_ca1Group,&c,&p); LoadCA1ECOutWeights(); // DG->CA3 p._flag = ARI_PROJECTION_FLAG_UNIRNDTON; p._probability = 0.04; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.9; c._weight._variance = 0.01; c.InitSpec(0.324, 1.0, 1.0); c.InitLearn(0.0, 0.0);

(40)

if(totalConn) _ca3Group.AddInputFrom(&_dgGroup,&c,&p, CID_DG_CA3); // CA3->CA3 p._flag = ARI_PROJECTION_FLAG_NTON; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.5; c._weight._variance = 0.25; c.InitSpec(20.25, 1.0, 1.0); c.InitLearn(0.1, 0.0); if(totalConn) _ca3Group.AddInputFrom(&_ca3Group,&c,&p, CID_CA3_CA3); // init _ecInGroup.Init(36, 0.25); _ecOutGroup.Init(36, 0.25); _dgGroup.Init(6, 0.25); _ca3Group.Init(12, 0.25); _ca1Group.Init(36, 0.25); }

void CMainFrame::GroupToSubGroups(ARI_LeabraNeuronGroup * pGroup, ARI_LeabraNeuronGroup * pSubGroups, unsigned int srcX, unsigned int srcY, unsigned int ratioX, unsigned int ratioY)

{

ARI_LeabraNeuron * pN;

unsigned int zX,zY,x,y,index;

for(zY=0; zY < ratioY; zY++)

for(zX=0; zX < ratioX; zX++) { for(y=0;y<srcY/ratioY;y++) for(x=0;x<srcX/ratioX;x++) { index = y * srcX + x + zX * (srcX/ratioX) + zY * (srcX * srcY/ratioY); pN = (ARI_LeabraNeuron*)(pGroup- >GetAt(index)); pSubGroups[zY*ratioX+zX].Add(pN); } } } void CMainFrame::CalcError() { ARI_IFNeuronGroup * pG1 = &_testGroup; ARI_LeabraNeuronGroup * pG2 = &_ecOutGroup; ARI_LeabraNeuron * pN1, * pN2;

double err_off = 0.0, err_on = 0.0, stm_err_on, stm_err_off;

bool rmbr;

(41)

for(pG1->FirstW(); ! pG1->EndW(); pG1->NextW()) {

pN1 = (ARI_LeabraNeuron*)pG1->GetW();

pN2 = (ARI_LeabraNeuron*)pG2->GetW();

if( (pN1->GetOutput() == 0.0) && (pN2->GetOutput() > 0.0) ) err_on++;

if( (pN1->GetOutput() > 0.0) && (pN2->GetOutput() == 0.0) ) err_off++;

pG2->NextW(); }

stm_err_on = err_on / 36.0; stm_err_off = err_off / 36.0;

if( (stm_err_on < 0.2) && (stm_err_off < 0.4) )

rmbr = true;

else

rmbr = false;

double doff = _stm_err_off - stm_err_off; double don = _stm_err_on - stm_err_on; if( (doff < 0.01) && (don < 0.01) ) {

_errorFrame++; }

else

_errorFrame = 0;

if((_errorFrame > 30.0) && (_status>0) && (stm_err_off < 1.0)) { _errorFrame = 0; _stm_err_off = 0.0; _stm_err_on = 0.0; // _result.PushInt(_status); _result.PushInt(_statusStep); if(_driverFile.IsAB()) _result.Push("AB"); else _result.Push("AC"); if(_driverFile.IsTraining()) _result.Push("TRAIN"); else _result.Push("TEST"); _result.PushInt(_result.Rows()%_driverFile.GetRows()); _result.PushInt(_driverFile.GetCurrentRow()); _result.PushFloat(stm_err_on); _result.PushFloat(stm_err_off); // _result.Dump(); // OnTrainingStep(); } else { _stm_err_off = stm_err_off; _stm_err_on = stm_err_on;

(42)

}

CString msg;

msg.Format("LAST:%s %s %s - step: %i - status: %i - sron: %f – sroff: %f - rmbr:%i - frame: %u",

_result.Read("DATA",_result.Rows()-1), _result.Read("TR/TE",_result.Rows()-1), _result.Read("PROG",_result.Rows()-1), _statusStep, _status, stm_err_on, stm_err_off, rmbr, _errorFrame); _view.SetWindowText(msg); } void CMainFrame::InitPreWeights() { TabData w1,w2; w1.FromFile(_myDir+"ABAC\\pesi_ecIn_ca1.wts"); w2.FromFile(_myDir+"ABAC\\pesi_ca1_ecOut.wts"); ARI_LeabraNeuron * pN; ARI_LeabraNeuronConnection * pC; unsigned int ratioX = 2, ratioY = 6;

unsigned int zX,zY,x,y,index,count,indexGP;

double w;

// ECin -> CA1 (id 1)

for(zY=0; zY < ratioY; zY++)

for(zX=0; zX < ratioX; zX++) {

for(y=0;y<CA1Y/ratioY;y++)

for(x=0;x<CA1X/ratioX;x++) {

index = y * CA1X + x + zX * (CA1X/ratioX) + zY * (CA1X * CA1Y/ratioY); indexGP = y * CA1X/ratioX + x; pN = (ARI_LeabraNeuron*)_ca1Group.GetAt (index); count = 0; for(pN->FirstWCInput(); !pN->EndWCInput(); pN->NextWCInput()) { pC = (ARI_LeabraNeuronConnection*)pN->GetWCInput(); if(pC->_connectionSpec._id == 1) { w = w1.ReadFloat(0,4 + count + indexGP*(4+12)); pC->_connectionSpec. _weight._value = w; // TRACE("CA1:%u CONN:%u W:%f\n",indexGP,count,w); count++; } } } }

(43)

// CA1 -> ECout (id 2)

for(zY=0; zY < ratioY; zY++)

for(zX=0; zX < ratioX; zX++) { for(y=0;y<ECOUTY/ratioY;y++) for(x=0;x<ECOUTX/ratioX;x++) { index = y * ECOUTX + x + zX * (ECOUTX/ratioX) + zY * (ECOUTX * ECOUTY/ratioY); indexGP = y * ECOUTX/ratioX + x; pN = (ARI_LeabraNeuron*)_ecOutGroup. GetAt(index); count = 0; for(pN->FirstWCInput(); !pN->EndWCInput(); pN->NextWCInput()) { pC = (ARI_LeabraNeuronConnection*)pN->GetWCInput(); if(pC->_connectionSpec._id == 2) { w = w2.ReadFloat(0,4 + count +indexGP*(4+32)); pC->_connectionSpec ._weight._value = w; // TRACE("ECOUT:%u CONN:%u W:%f\n",indexGP,count,w); count++; } } } } } void CMainFrame::LoadECInCA1Weights() { TabData w1; w1.FromFile(_myDir+"ABAC\\pesi_ecIn_ca1.wts"); ARI_LeabraNeuron * pN; ARI_LeabraNeuronConnection * pC; unsigned int ratioX = 2, ratioY = 6;

unsigned int zX,zY,x,y,index,count,indexGP;

double w;

// ECin -> CA1 (id 1)

for(zY=0; zY < ratioY; zY++)

for(zX=0; zX < ratioX; zX++) {

for(y=0;y<CA1Y/ratioY;y++)

for(x=0;x<CA1X/ratioX;x++) {

index = y * CA1X + x + zX * (CA1X/ratioX) + zY * (CA1X * CA1Y/ratioY); indexGP = y * CA1X/ratioX + x; pN = (ARI_LeabraNeuron*)_ca1Group .GetAt(index); count = 0; for(pN->FirstWCInput(); !pN->EndWCInput(); pN->NextWCInput())

(44)

{ pC = (ARI_LeabraNeuronConnection*)pN ->GetWCInput(); if(pC->_id == CID_ECIN_CA1) { w = w1.ReadFloat(0,4 + count + indexGP*(4+12)); pC->_connectionSpec. _weight._value = w; // TRACE("CA1:%u CONN:%u W:%f\n",indexGP,count,w); count++; } } } } } void CMainFrame::OnProc() {

// TODO: Add your command handler code here _driverFile.ResetEpoch(); _inputGroup.SetOutput(0.0); _ecInGroup.Reset(); _ecOutGroup.Reset(); _dgGroup.Reset(); _ca3Group.Reset(); _ca1Group.Reset(); _result.Reset(8); _result.SetTitle(0,"STATUS"); _result.SetTitle(1,"STEP"); _result.SetTitle(2,"DATA"); _result.SetTitle(3,"TR/TE"); _result.SetTitle(4,"PROG"); _result.SetTitle(5,"INDEX"); _result.SetTitle(6,"errON"); _result.SetTitle(7,"errOFF"); SetTrainingAB(); _stm_err_off = 0.0; _stm_err_on = 0.0; _errorFrame = 0; _status = FIRST_STAGE; _statusStep = 0; _driverFile.Update(0.0); } void CMainFrame::UpdateStatus() {

// 3 * [ Tr(AB) + Te(AB) + Te(AC) ]

if(_status == 1) { if(_driverFile.GetDeltaEpoch() == 1) { _status = 2; DisconnectECInCA1(); SetTestAB(); return;

(45)

} } if(_status == 2) { if(_driverFile.GetDeltaEpoch() == 1) { _status = 3; SetTestAC(); return; } } if(_status == 3) { if(_driverFile.GetDeltaEpoch() == 1) { _statusStep++; if(_statusStep == 3) { _statusStep = 0; _status = SECOND_STAGE; ConnectECInCA1(); SetTrainingAC(); return; } else { _status = FIRST_STAGE; ConnectECInCA1(); SetTrainingAB(); return; } } }

// 5 * [ Tr(AC) + Te(AB) + Te(AC) ]

if(_status == 4) { if(_driverFile.GetDeltaEpoch() == 1) { _status = 5; DisconnectECInCA1(); SetTestAB(); return; } } if(_status == 5) { if(_driverFile.GetDeltaEpoch() == 1) { _status = 6; SetTestAC(); return; } } if(_status == 6) { if(_driverFile.GetDeltaEpoch() == 1) { _statusStep++; if(_statusStep == 5)

(46)

{ _status = 0; _result.ToFile(".\\result.txt"); CMATOUT("AIO'","Finito"); return; } else { _status = SECOND_STAGE; ConnectECInCA1(); SetTrainingAC(); return; } } } } void CMainFrame::ConnectECInCA1() { ARI_LeabraNeuronConnectionSpec c; ARI_ProjectionSpec p; p._flag = ARI_PROJECTION_FLAG_GP1TO1; p._gpDestX = CA1X; p._gpSrcX = ECINX; p._gpRatioX = 2; p._gpRatioY = 6; c._weight._flag = ARI_VALUE_FLAG_UNIGAUSSRND; c._weight._mean = 0.9; c._weight._variance = 0.01; c.InitSpec(0.5833333333333, 6.0, 1.25, 12); c.InitLearn(0.0, 0.0); _ca1Group.AddInputFrom(&_ecInGroup,&c,&p, CID_ECIN_CA1); LoadECInCA1Weights(); } void CMainFrame::DisconnectECInCA1() { _ca1Group.RemoveInputFrom(CID_ECIN_CA1); }

Per la gestione dei pattern AB e AC che vengono generati dalla funzione LeabraMakeInput

del MainFrame abbiamo creato un’ulteriore classe ARI_ABACSensorDriver che gestisce i

dati memorizzati su file esterni.

ARI_ABACSensorDriver.h

#ifndef __ARI_ABAC_SENSORDRIVER__ #define __ARI_ABAC_SENSORDRIVER__ #include <TabData.h>

(47)

#include <ARI_SensorDriver.h> #include <ARI_Matrix.h>

//ARI_ABACSensorDriver è un ARI_SensorDriver e consente di utilizzare //come input un file di testo in formato DataEngine.

//Vuole due gruppi contigui. Il secondo è per il test. class ARI_ABACSensorDriver: public ARI_SensorDriver {

public:

//Importa i dati in RAM ed inizializza il driver invocando InitDriver() //e specificando un numero di IFNeurons da registrare pari a

//(numFeatures+numClasses).

//Inizializza l'urna delle righe da estrarre.

bool Init(

const CString & fileNameAB,

const CString & fileNameAC,

unsigned int numFeaturesContext,

unsigned int numFeaturesBC,

unsigned int numFeaturesA,

unsigned int featuresStartColIndex = 0,

unsigned int featuresStartRowIndex = 0,

double featuresOffset = 0.0,

double featuresScale = 1.0);

//Estrae una riga a sorte dall'urna.

//Se l'urna è vuota la riempie di nuovo ed incrementa il contatore di //epoche.

void Update(double dt);

bool IsAB() { return _ABNotAC; }

bool IsAC() { return !_ABNotAC; }

bool IsTraining() { return _trainingNotTest; }

bool IsTest() { return !_trainingNotTest; }

void SetAB() { _ABNotAC = true; }

void SetAC() { _ABNotAC = false; }

void SetTraining() { _trainingNotTest = true; }

void SetTest() { _trainingNotTest = false; }

void ResetEpoch() { _epoch = 0; _oldEpoch = 0;

_urn.UndoAll(); }

int GetCurrentRow() { return _currentRow; }

int GetRows() { return _matrixAB.Rows(); }

//Ritorna l'epoca corrente.

unsigned int GetEpoch() { return _epoch; }

//Ritorna 1 se c'è stato un cambiamento di epoca, altrimenti 1. //Va interrogato dopo l'update del driver.

unsigned int GetDeltaEpoch() { unsigned int de = _epoch – _oldEpoch; _oldEpoch = _epoch; return de; } private:

(48)

unsigned int _epoch, _oldEpoch, _numFeaturesContext, _numFeaturesBC, _numFeaturesA;

ARI_Matrix _matrixAB, _matrixAC;

CUrn<int> _urn; int _currentRow; }; #endif ARI_ABACSensorDriver.cpp #include "stdafx.h" #include <ARI_ABACSensorDriver.h> #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

bool ARI_ABACSensorDriver::Init(

const CString & fileNameAB,

const CString & fileNameAC,

unsigned int numFeaturesContext,

unsigned int numFeaturesBC,

unsigned int numFeaturesA,

unsigned int featuresStartColIndex,

unsigned int featuresStartRowIndex,

double featuresOffset,

double featuresScale)

{

unsigned int numFeatures = numFeaturesContext+numFeaturesBC+ numFeaturesA; InitDriver("ARI_ABACSensorDriver", 2*numFeatures); _epoch = 0; _oldEpoch = 0; _ABNotAC = true; _trainingNotTest = true; _numFeaturesContext = numFeaturesContext; _numFeaturesBC = numFeaturesBC; _numFeaturesA = numFeaturesA; TabData dataAB; if(!dataAB.FromFile(fileNameAB)) return false; TabData dataAC; if(!dataAC.FromFile(fileNameAC)) return false;

if( (dataAB.Rows() != dataAC.Rows()) || (dataAB.Cols() != dataAC.Cols()) )

return false;

int cols = numFeatures;

int rows = dataAB.Rows() - featuresStartRowIndex;

int x,y;

for(y = 0; y<rows; y++) _urn.Add(y);

(49)

_matrixAB.Init(cols,rows); _matrixAC.Init(cols,rows);

double valueAB, valueAC; for(y=0; y<rows; y++)

for(x=0;x<cols;x++) { if(x < numFeatures) { valueAB = (dataAB.ReadFloat (featuresStartColIndex+x,featuresStartRowIndex+y) - featuresOffset) / featuresScale; valueAC = (dataAC.ReadFloat (featuresStartColIndex+x,featuresStartRowIndex+y) – featuresOffset) / featuresScale; } else { valueAB = dataAB.ReadFloat (featuresStartColIndex+x,featuresStartRowIndex+y); valueAC = dataAC.ReadFloat (featuresStartColIndex+x,featuresStartRowIndex+y); } _matrixAB.SetAt(x,y,valueAB); _matrixAC.SetAt(x,y,valueAC); } return true; } void ARI_ABACSensorDriver::Update(double dt) { if(!IsRegistered()) return; _currentRow = _urn.DrawingOfLots(); // int y = _urn.Cheat(0);

unsigned int numFeatures = _numFeaturesContext+_numFeaturesBC+ +_numFeaturesA;

double value;

for(unsigned int i=0;i<numFeatures;i++)

if(_pIFNeurons[i]) { if(_ABNotAC) value = _matrixAB.GetAt(i,_currentRow); else value = _matrixAC.GetAt(i,_currentRow);

if( (i>=_numFeaturesContext) &&

(i<(_numFeaturesContext+_numFeaturesBC)) ) { if(_trainingNotTest) _pIFNeurons[i]->SetOutput(value); else _pIFNeurons[i]->SetOutput(0.0); } else _pIFNeurons[i]->SetOutput(value);

(50)

_pIFNeurons[numFeatures+i]->SetOutput(value); } if(!_urn.Count()) { _urn.UndoAll(); _epoch++; // ARI_Log1("Epoch: %u",_epoch); } }

Riferimenti

Documenti correlati

La seconda parte del capitolo tratta il passaggio, avvenuto nel 1942, dalla gestione degli Immobili a quella del neonato Ente Teatrale Italiano (ETI), in seguito alla quale il

Despite the difficulties dyslexic students can find while learning a foreign language, it is important for them and all the people around them (including teachers,

Negli ultimi anni, il settore dell'industria alimentare cinese ha registrato un rapido sviluppo, con un tasso di crescita media annua superiore al 20%, pari al doppio

In Chapter III, the Authors will focus on the risks and trade-offs of the Commission’s choice to support the deployment of an all fibre network, while bearing in mind

Students, staff, employers and the institutional community engage in higher education with different literacies, different ambitions and different aesthetics and technology,

Smentendo l’idea dell’inesistenza della nozione di individualità nel pensiero cinese diffusasi in Occidente, la prima parte della trattazione mette in luce la centralità

As far as Hindi is concerned, a subordinate clause hosting a subjunctive allows a coreference reading between the matrix third person pronoun and the embedded one, while for

It may prove particularly useful in projects where II investments supplement governmental funds from national or international actors (e.g. the Global Environmental