#include #include #include #include using namespace std; namespace icl{ namespace som{ static inline float distance2(const float *a,const float *b, unsigned int dim){ // {{{ open float sum = 0; for(unsigned int i=0;igridpos,gridpos,griddim*sizeof(float)); memcpy(this->prototype,prototype,datadim*sizeof(float)); } } // }}} SOM::Neuron::~Neuron(){ // {{{ open ICL_DELETE_ARRAY( gridpos ); ICL_DELETE_ARRAY( prototype ); } // }}} SOM::Neuron::Neuron(const Neuron &other):gridpos(0),prototype(0){ // {{{ open (*this)=other; } // }}} SOM::Neuron &SOM::Neuron::operator=(const Neuron &other){ // {{{ open griddim = other.griddim; datadim = other.datadim; gridpos = gridpos ? gridpos : new float[other.griddim]; prototype = prototype ? prototype : new float[other.datadim]; memcpy(gridpos,other.gridpos,griddim*sizeof(float)); memcpy(prototype,other.prototype,datadim*sizeof(float)); return *this; } // }}} SOM::SOM(unsigned int dataDim, const std::vector &dims,const std::vector > &prototypeBounds, float epsilon, float sigma){ // {{{ open ICLASSERT_THROW(dataDim>0,ICLException("SOM data dimension must be > 0")); ICLASSERT_THROW(dims.size()>0,ICLException("SOM grid dimension must be > 0")); m_uiDataDim = dataDim; m_uiSomDim = dims.size(); m_vecDimensions = dims; m_vecPrototypeBounds = prototypeBounds; m_fEpsilon = epsilon; m_fSigma = sigma; // count neuron count unsigned int dim = dims[0]; for(unsigned int i=1;i 0,ICLException("Product of SOM dimensions must be > 0")); m_vecNeurons.resize(dim); // calculate offsets for each dimension in the planar neurons array m_vecDimOffsets.resize(m_uiSomDim); m_vecDimOffsets[0] = 1; for(unsigned int i=1;i1 ? m_vecDimOffsets[i-1]*dims[i-1] : dims[i-1]; } // Create the neurons for(unsigned int i=0;i=0;--d){ gridpos[d] = iRest ? iRest/m_vecDimOffsets[d] : 0; iRest -= gridpos[d]*m_vecDimOffsets[d]; } ICLASSERT_THROW(iRest == 0,ICLException("Somethings going wrong here! [code 1240/B.l]") ); // create some randomly initialized prototypes (using the given ranges for each dimension) for(unsigned int d=0;d &SOM::getNeurons() const{ // {{{ open return m_vecNeurons; } // }}} vector &SOM::getNeurons(){ // {{{ open return m_vecNeurons; } // }}} const SOM::Neuron &SOM::getWinner(const float *input) const{ // {{{ open static Neuron dummy; ICLASSERT_RETURN_VAL(m_vecNeurons.size(),dummy); unsigned int minIdx = 0; float minDist = som::distance2(m_vecNeurons[0].prototype,input,m_uiDataDim); for(unsigned int i=0;i(const_cast(this)->getWinner(input)); } // }}} const SOM::Neuron &SOM::getNeuron(const std::vector &dims) const{ // {{{ open static Neuron dummy; ICLASSERT_RETURN_VAL(dims.size() == m_uiSomDim, dummy); unsigned int idx = 0; for(unsigned int i=0;i &dims){ // {{{ open return const_cast(const_cast(this)->getNeuron(dims)); } // }}} void SOM::setEpsilon(float epsilon){ // {{{ open m_fEpsilon = epsilon; } // }}} void SOM::setSigma(float sigma){ // {{{ open m_fSigma = sigma; } // }}} }