/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLMath/src/ICLMath/SOM.cpp ** ** Module : ICLMath ** ** Authors: Christof Elbrechter ** ** ** ** ** ** GNU LESSER GENERAL PUBLIC LICENSE ** ** This file may be used under the terms of the GNU Lesser General ** ** Public License version 3.0 as published by the ** ** ** ** Free Software Foundation and appearing in the file LICENSE.LGPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the license requirements will ** ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** ********************************************************************/ #include #include #include #include #include using namespace std; using namespace icl::utils; namespace icl{ namespace math{ namespace som{ static inline float distance2(const float *a,const float *b, unsigned int dim){ // {{{ open float sum = 0; for(unsigned int i=0;i &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.get(),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; } // }}} } // namespace math }