00001 #ifndef KOHONENT_H
00002 #define KOHONENT_H
00003
00004 #include "Kohonen.h"
00005
00006 namespace annie {
00007
00012 template<uint T_dimensions>
00013 class EucledianTopology : public Topology {
00014 public:
00018 typedef uint Axes[T_dimensions];
00019 EucledianTopology (const Axes &sizes);
00020
00021 virtual real getNeighborWeight(uint srcNeuron, uint destNeuron, real nbSize) const;
00022 virtual bool isGridNeighbor(uint srcNeuron, uint destNeuron) const;
00023
00024 uint getSize(uint axis) const { return sizes[axis]; }
00025 void id2Axes(uint id, Axes &out) const;
00026 Vector axes2Vector(const Axes &a) const;
00027 Axes sizes;
00028 };
00029
00030 template<uint T_dimensions>
00031 EucledianTopology<T_dimensions>::EucledianTopology(const EucledianTopology::Axes &sizes) {
00032 totalCount = 1;
00033 real mxd_2 = 0.;
00034 for(uint i=0; i<T_dimensions; i++) {
00035 this->sizes[i] = sizes[i];
00036 totalCount *= sizes[i];
00037 mxd_2 += sizes[i] * sizes[i];
00038 }
00039 maxDim = sqrt(mxd_2);
00040 }
00041
00042 template<uint T_dimensions>
00043 void EucledianTopology<T_dimensions>::id2Axes(uint id, EucledianTopology::Axes &indexes) const{
00044 for(uint i=0; i<T_dimensions; i++) {
00045 indexes[i] = id % sizes[i];
00046 id /= sizes[i];
00047 }
00048 }
00049
00050 template<uint T_dimensions>
00051 Vector EucledianTopology<T_dimensions>::axes2Vector(const Axes &a) const {
00052 Vector out(T_dimensions);
00053 for(uint i=0; i<T_dimensions; i++)
00054 out[i] = a[i];
00055 return out;
00056 }
00057
00058 template<uint T_dimensions>
00059 real EucledianTopology<T_dimensions>::getNeighborWeight(uint srcNeuron, uint destNeuron, real nbSize) const {
00060 assert(srcNeuron < totalCount);
00061 assert(destNeuron < totalCount);
00062
00063 Axes a;
00064 id2Axes(srcNeuron, a);
00065 Vector sa = axes2Vector(a);
00066 id2Axes(destNeuron, a);
00067 Vector da = axes2Vector(a);
00068
00069
00070
00071 if(sa.distance(da) <= nbSize) return 1.0;
00072 else return 0.;
00073 }
00074
00075 template<uint T_dimensions>
00076 bool EucledianTopology<T_dimensions>::isGridNeighbor(uint srcNeuron, uint destNeuron) const {
00077
00078 return getNeighborWeight(srcNeuron, destNeuron, 1.) == 1.;
00079
00080
00081
00082
00083
00084 }
00085
00086 }
00087 #endif //_H