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); }
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 {
}; 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(); }
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(); }
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
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))
(*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;
};
#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);
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;
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);
#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);
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();
// 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); }
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(); } }
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++; } } //
// 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;
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); }
// 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");
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;
#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();
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);
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
#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;
{
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); } }
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
#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;
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>
#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;
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
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,
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;
// 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
_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);
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++;
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;
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); }
} }
}
// 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); }
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),
_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);
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;
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;
}
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++; } } } }
// 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())
{ 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;
} } 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)
{ _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>
#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:
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);
_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);
_pIFNeurons[numFeatures+i]->SetOutput(value); } if(!_urn.Count()) { _urn.UndoAll(); _epoch++; // ARI_Log1("Epoch: %u",_epoch); } }