00001 #ifndef TwoD_H
00002 #define TwoD_H
00003
00004 #include "TopologyImp.h"
00005
00006
00007
00016 class TwoD : public TopologyImp {
00017 public:
00019 Value_Type distance(int bmu, int i, int dimensions[MaxDimension], int type);
00020
00022 int Coord( int pos, int axis, int dimensions[MaxDimension] );
00023
00025 TMatrix LinInitCoords(int mapsize, int dimensions[MaxDimension]);
00026
00028 TMatrix CreateDelta( int dimensions[MaxDimension], int lattice, int mapsize );
00029
00031 Value_Type H( const Value_Type delta, Value_Type radius, int neighboor );
00032
00034 vector<int> getNeighbors( int i, int neighbor, int dimensions[] );
00035
00037 TwoD(const TopolParams& par):TopologyImp(par) {};
00038
00039 private:
00040 Value_Type hexa_dist(int bx, int by, int tx, int ty);
00041
00042 Value_Type rect_dist(int bx, int by, int tx, int ty);
00043 };
00044
00045 vector<int> TwoD::getNeighbors( int i, int neighbor, int dimensions[] ) {
00046
00047 int L = dimensions[0] - 1;
00048 int C = dimensions[1] - 1;
00049 int y = Coord( i, 0, dimensions );
00050 int x = Coord( i, 1, dimensions );
00051 vector<int> neighbors;
00052
00053
00054
00055 if ( neighbor = HEXA ) {
00056
00057 if ( fmod( y, 2 ) != 0) {
00058
00059 if ( ( x - 1 >= 0 ) )
00060 neighbors.push_back( ( (x-1)*(L+1) +y +1 ) );
00061
00062 if ( (y + 1) <= L )
00063 neighbors.push_back( (x)*(L+1) + y + 2 );
00064
00065 if ( ((x + 1) <= C ) && ((y + 1) <= L) )
00066 neighbors.push_back( ( (x+1)*(L+1) + y + 2) );
00067
00068 if ( (x + 1) <= C )
00069 neighbors.push_back( ( (x+1)*(L+1) + y + 1) );
00070
00071 if ( ( (y - 1) >= 0 ) && ( x + 1 <= C ) )
00072 neighbors.push_back( ((x+1)*(L+1) + y ) );
00073
00074 if ( (y - 1) >= 0 )
00075 neighbors.push_back( ( (x)*(L+1)+y ) );
00076
00077
00078 } else {
00079
00080 if ( x - 1 >= 0)
00081 neighbors.push_back( (x-1)*(L+1) + y + 1 );
00082
00083 if ((x-1>=0) && (y+1 <= L))
00084 neighbors.push_back( (x-1)*(L+1) + y + 2 );
00085
00086 if ( y + 1 <= L )
00087 neighbors.push_back( x*(L+1) + y + 2 );
00088
00089 if ( x + 1 <= C )
00090 neighbors.push_back( (x+1)*(L+1) + y + 1 );
00091
00092 if ( y - 1 >= 0 )
00093 neighbors.push_back( x*(L+1) + y );
00094
00095 if ((x-1 >= 0) && (y-1) >= 0)
00096 neighbors.push_back( (x-1)*(L+1) + y );
00097
00098 }
00099
00100
00101 } else if ( neighbor = RECT ) {
00102
00103 if ( (y - 1) >= 0 )
00104 neighbors.push_back( ( (x-1)*L+y ) );
00105
00106 if ( ( x - 1 >= 0 ) )
00107 neighbors.push_back( ( (x-2)*L +y +1 ) );
00108
00109 if ( (x + 1) <= C )
00110 neighbors.push_back( ( x*L + y + 1) );
00111
00112 if ( (y + 1) <= L )
00113 neighbors.push_back( (x-1)*L + y + 2 );
00114 }
00115
00116
00117 return neighbors;
00118
00119 };
00120
00121
00122 Value_Type TwoD::H( const Value_Type delta, Value_Type radius, int neighboor ) {
00123
00124 switch(neighboor) {
00125 case GAUSSIAN : return exp( -delta*delta/2*radius*radius); break;
00126
00127 case BUBBLE : if (delta <= radius )
00128 return 1;
00129 else
00130 return 0;
00131 break;
00132 case CUTGAUSS : if (delta <= radius )
00133 return exp( -delta*delta/2*radius*radius);
00134 else
00135 return 0;
00136 break;
00137 case EP : if (delta <= radius )
00138 return (1 - delta*delta/radius*radius);
00139 else
00140 return 0;
00141 break;
00142 }
00143 return 0;
00144 };
00145
00146
00147
00148 TMatrix
00149 TwoD::CreateDelta(int dimensions[MaxDimension], int lattice, int mapsize ) {
00150 int i, j;
00151 TMatrix delta = create_matrix(1, mapsize, 1, mapsize);
00152 for (i=1; i<=mapsize ; i++) for (j=i; j<= mapsize; j++)
00153 delta[i][j] = delta[j][i] = distance( i, j, dimensions, lattice );
00154 return delta;
00155 }
00156
00157
00158
00159 TMatrix
00160 TwoD::LinInitCoords(int mapsize, int dimensions[MaxDimension]) {
00161 int i,k;
00162 int dimension = 2;
00163 TMatrix LinInitCoords = create_matrix(1,mapsize,1,dimension);
00164 TVector Max = create_vector(1,2);
00165 TVector Min = create_vector(1,2);
00166
00167 for (i=1;i<=2;i++) {Max[i] = 0.0; Min[i] = 100000.0;};
00168
00169 for (i=1;i<=mapsize;i++) {
00170 LinInitCoords[i][1] = Coord(i, 2, dimensions );
00171 LinInitCoords[i][2] = Coord(i, 1, dimensions );
00172 if ( LinInitCoords[i][1] > Max[1] ) Max[1] = LinInitCoords[i][1];
00173 if ( LinInitCoords[i][2] > Max[2] ) Max[2] = LinInitCoords[i][2];
00174 if ( LinInitCoords[i][1] < Min[1] ) Min[1] = LinInitCoords[i][1];
00175 if ( LinInitCoords[i][2] < Min[2] ) Min[2] = LinInitCoords[i][2];
00176 }
00177 for (i=1;i<=mapsize;i++)
00178 for (k=1;k<=dimension;k++)
00179 if (Max[k] > Min[k])
00180 LinInitCoords[i][k] = ((LinInitCoords[i][k] - Min[k])/(Max[k] - Min[k]) - 0.5)*2.0;
00181 else
00182 LinInitCoords[i][k] = 0.0;
00183
00184 return LinInitCoords;
00185 };
00186
00187
00188
00189 int
00190 TwoD::Coord( int pos, int axis, int dimensions[MaxDimension] ) {
00191 Value_Type x, y, tmp1, tmp2, N, M;
00192
00193 N = dimensions[0];
00194 M = dimensions[1];
00195
00196 tmp1 = pos % (int)N;
00197 tmp2 = floor(pos/(int)N);
00198
00199 if (pos <= N) { x = 0; y = pos - 1; }
00200 else
00201 if (tmp1 == 0) { y = N - 1; x = tmp2 - 1; }
00202 else { y = tmp1 - 1; x = tmp2; };
00203
00204 if ( axis ==1 )
00205 return (int)x;
00206 else
00207 return (int)y;
00208 };
00209
00210
00211
00212 Value_Type
00213 TwoD::hexa_dist(int bx, int by, int tx, int ty)
00214 {
00215 Value_Type ret, diff;
00216
00217 diff = bx - tx;
00218
00219 if (((by - ty) % 2) != 0) {
00220 if ((by % 2) == 0) {
00221 diff -= 0.5;
00222 }
00223 else {
00224 diff += 0.5;
00225 }
00226 }
00227
00228 ret = diff * diff;
00229 diff = by - ty;
00230 ret += 0.75 * diff * diff;
00231 ret = (Value_Type) sqrt((Value_Type) ret);
00232
00233 return(ret);
00234 }
00235
00236
00237
00238 Value_Type
00239 TwoD::rect_dist(int bx, int by, int tx, int ty)
00240 {
00241 Value_Type ret, diff;
00242
00243 diff = bx - tx;
00244 ret = diff * diff;
00245 diff = by - ty;
00246 ret += diff * diff;
00247 ret = (Value_Type) sqrt((Value_Type) ret);
00248
00249 return(ret);
00250 }
00251
00252
00253
00254 Value_Type
00255 TwoD::distance(int bmu, int i, int dimensions[MaxDimension], int type) {
00256 Value_Type x1, y1, x2, y2;
00257
00258 x1 = Coord( bmu, 1, dimensions );
00259 y1 = Coord( bmu, 2, dimensions );
00260 x2 = Coord( i, 1, dimensions );
00261 y2 = Coord( i, 2, dimensions );
00262 if (type == HEXA)
00263 return hexa_dist( (int)x1, (int)y1,(int) x2,(int) y2 );
00264 else
00265 return rect_dist( (int)x1, (int)y1, (int)x2, (int)y2 );
00266 };
00267
00268
00269 #endif