Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
SubZer0MS authored Dec 26, 2016
1 parent c01aac2 commit 1301c57
Show file tree
Hide file tree
Showing 9 changed files with 903 additions and 0 deletions.
71 changes: 71 additions & 0 deletions SOM/inc/CController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef CCONTROLLER_H
#define CCONTROLLER_H


//------------------------------------------------------------------------
//
// Name: CController.h
//
// Desc: controller class for the SOM demo
//
// Author: Mat Buckland 2002 ([email protected])
//
//------------------------------------------------------------------------

#include <windows.h>
#include <vector>

using namespace std;

#include "CNode.h"
#include "Csom.h"
#include "constants.h"


class CController
{

private:

//pointer to a Self Organising Map
Csom* m_pSOM;

//the data for the training
vector<vector<double> > m_TrainingSet;


//this method creates a small data set of color values
//that are used to train the network with
void CreateDataSet();


public:

CController(int cxClient, int cyClient, int CellsUp, int CellsAcross, int NumIterations)
{
//create the SOM
m_pSOM = new Csom();

m_pSOM->Create(cxClient, cyClient, CellsUp, CellsAcross, NumIterations);

//create the training set
CreateDataSet();
}

~CController()
{
delete m_pSOM;
}

void Render(HDC surface);

bool Train();

bool Finished()const{return m_pSOM->FinishedTraining();}



};


#endif
59 changes: 59 additions & 0 deletions SOM/inc/CNode.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef CNode_H_
#define CNode_H_

#include <vector>
#include <string>

#include "utils.h"

using namespace std;

class CNode
{

private:

vector<double> m_dWeights;
double m_dPosX;
double m_dPosY;


public:

CNode(double posX, double posY, int numWeights):
m_dPosX(posX),
m_dPosY(posY)
{
/*
* initialize the weights to small random variables
*/
for(int w = 0; w < numWeights; w++)
{
m_dWeights.push_back(RandFloat());
}
}

/*
* returns the euclidean distance (squared)
* between the node's weights and the input vector
*/
inline double GetEucDistance(
const vector<double> &vecInput
);

/*
* given a learning rate and a target vector,
* this function adjusts the node's weights accordingly
*/
inline void AdjustWeights(
const vector<double> &vecTarget,
const double learningRate,
const double influence
);

double getPosX() const { return m_dPosX; }
double getPosY() const { return m_dPosY; }

};

#endif
66 changes: 66 additions & 0 deletions SOM/inc/CSom.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef CSOM_H_
#define CSOM_H_

#include <vector>

using namespace std;

#include "CNode.h"
#include "constants.h"


class CSom
{

private:

vector<CNode> m_SOM; //the neurons representing the Self Organizing Map
CNode* m_pWinningNode; //this holds the address of the winning node from the current iteration
double m_dMapRadius; //this is the topological 'radius' of the feature map
double m_dTimeConstant; //used in the calculation of the neighbourhood width of influence
int m_iNumIterations; //the number of training iterations
int m_iIterationCount; //keeps track of what iteration the epoch method has reached
double m_dNeighbourhoodRadius; //the current width of the winning node's area of influence
double m_dInfluence; //how much the learning rate is adjusted for nodes within the area of influence
double m_dLearningRate; // the learning rate
bool m_bDone; //set true when training is finished
double m_dCellWidth; //the height and width of the cells that the nodes occupy when rendered into 2D space.
double m_dCellHeight; //the height and width of the cells that the nodes occupy when rendered into 2D space.


CNode* FindBestMatchingNode(const vector<double> &vecInput);

inline double GetGaussianDistance(const double dist, const double sigma);


public:

CSom():
m_dCellWidth(0),
m_dCellHeight(0),
m_pWinningNode(NULL),
m_iIterationCount(1),
m_iNumIterations(0),
m_dTimeConstant(0),
m_dMapRadius(0),
m_dNeighbourhoodRadius(0),
m_dInfluence(0),
m_dLearningRate(constStartLearningRate),
m_bDone(false)
{}

void Create(
int cxClient,
int cyClient,
int CellsUp,
int CellsAcross,
int NumIterations
);

bool Epoch(const vector<vector<double>> &data);

bool FinishedTraining() const { return m_bDone; }

};

#endif
20 changes: 20 additions & 0 deletions SOM/inc/constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef CONSTANTS_H_
#define CONSTANTS_H_

const int constNumCellsAcross = 40;
const int constNumCellsDown = 40;


//number of weights each node must contain. One for each element of
//the input vector. In this example it is 3 because a color is
//represented by its red, green and blue components. (RGB)
const int constSizeOfInputVector = 3;

//the number of epochs desired for the training
const int constNumIterations = 1000;

//the value of the learning rate at the start of training
const double constStartLearningRate = 0.1;


#endif
86 changes: 86 additions & 0 deletions SOM/inc/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#ifndef UTILS_H_
#define UTILS_H_

#include <stdlib.h>
#include <math.h>
#include <sstream>
#include <string>
#include <iostream>
#include <vector>

using namespace std;

// returns a random integer between x and y
inline int RandInt(int x, int y)
{
return rand() % (y - x + 1) + x;
}

// returns a random float between zero and 1
inline double RandFloat()
{
return (rand()) / (RAND_MAX + 1.0);
}

// returns a random bool
inline bool RandBool()
{
if(RandInt(0,1)) return true;
else return false;
}

// returns a random float in the range -1 < n < 1
inline double RandClamped()
{
return RandFloat() - RandFloat();
}

// converts an integer to a string
inline string itos(int arg)
{
ostringstream buffer;
buffer << arg;

return buffer.str();
}

// converts a float to a string
inline string ftos(float arg)
{
ostringstream buffer;
buffer << arg;

return buffer.str();
}

// clamps the first argument between the second two
inline void Clamp(
double &arg,
const double min,
const double max
) {
if(arg < min) arg = min;
if(arg > max) arg = max;
}


// rounds a double up or down depending on its value
inline int Rounded(double val)
{
int integral = (int)val;
double mantissa = val - integral;

return (mantissa < 0.5 ? integral : ++integral);
}

// rounds a double up or down depending on whether its
// mantissa is higher or lower than offset
inline int RoundUnderOffset(double val, double offset)
{
int integral = (int)val;
double mantissa = val - integral;

return (mantissa < offset ? integral : ++integral);
}

#endif
Loading

0 comments on commit 1301c57

Please sign in to comment.