// DLMindex.C #include "nsl_include.h" #include "DLMwin.h" #include "DLMSimilarity.h" #include "DLM.h" // ==== index functions ================================================= ; /* There are several index functions in order to switch between layer 1 or 2 indices and the respective entry indices of the connectivity matrices. For layers 1 and 2 as well as for the connectivity patches in layer 1 there are two systems of indices. The first is a pair of indices like (i1,j1) to indicate the two-dimensional location. The second system is just one index like ij1 indicating the position of a cell in the corresponding vector representation. You get the vector representation just by concatenating the rows of the respective matrix. 0 . . . . . j1 . . . . . . j1max-1 0 +----------------------------+ 0 . . j2 . . j2max-1 . | | 0 +--------------+ . | | . | | . | | . | | . | 0 . j1R . j1Rmax-1 | . | | . | 0 +-----------+ | i2 | (*) | . | . | patch for | | . | | | . | cell (*) | | . | layer 2 | i1 | i1R| in | | . | | . | . | layer 2 | | i2max-1+--------------+ . | . | | | . | i1Rmax-1+-----------+ | . | | . | | . | layer 1 | . | | i1max-1+----------------------------+ Fig.1: Matrix representation of layer 1, 2, and the connectivity patch from cell (*) in layer 2 to layer 1. | vector index | matrix index | ij2 | (i2,j2) -------------------+---------------------- 0 | (0,0) 1 | (0,1) 2 | (0,2) : | : j2max-1 | (0,j2max-1) j2max | (1,0) : | (1,1) : | : : | (1,j2max-1) 2*j2max | (2,0) : | : i2max*j2max-1 | (i2max-1,j2max-1) | Fig.2: Correspondent indices of vector and matrix representation of layer 2. Each cell in layer 2 is connected to a patch of cells in layer 1. The size of the patches is always i1Rmax x j1Rmax, but their position depends on the position of the corresponding cell in layer two. We consider only one dimension. Regarding the i1-index the patches can have (i1max-i1Rmax+1) different offsets varying in the range [0,..,(i1max-i1Rmax)]. These offsets should be equally distributed on i2max different positions in the range [0,..,i2max-1] in layer 2. Since i2/float(i2max-1) lies in [0,..,1], (i1max-i1Rmax)*i2/float(i2max-1) covers the correct range [0,..,(i1max-i1Rmax)]. In order to round it to the closest integer we take int((i1max-i1Rmax)*i2/float(i2max-1)+0.5). Given a layer 1 of size 7 and a patch size of 4, there are 4 different offsets. For a layer 2 of size 6 the offsets are shown in Fig.3. i1 0 . . . . 1 . . . . 2 . . . . 3 . . . . 4 . . . . 5 . . . . 6 patch 0 . . . . 1 . . . . 2 . . . . 3 offsets 0 . . . . 1 . . . . 2 . . . . 3 | / \ / \ | correspondence between i2 | / \ / \ | and the respective offset i2 0 . . 1 . . 2 . . 3 . . 4 . . 5 Fig.3: The offsets of the connection patches depending on the source cell i2. The relations between the indices i1, i1R, and i2 are shown in fig.4 and fig.5. The index matrix in fig.5 is the one-dimensional analogue to the connectivity of matrix W21. The entries of W21 are of course not the indices itself but the weights for the respective weights. i1 0 . . . . 1 . . . . 2 . . . . 3 . . . . 4 . . . . 5 . . . . 6 i2 0 0 . . . . 1 . . . . 2 . . . . 3 1 0 . . . . 1 . . . . 2 . . . . 3 i1R 2 0 . . . . 1 . . . . 2 . . . . 3 3 0 . . . . 1 . . . . 2 . . . . 3 4 0 . . . . 1 . . . . 2 . . . . 3 5 0 . . . . 1 . . . . 2 . . . . 3 Fig.4: i1R depending on i1 and i2. i1R 0 . . . . 1 . . . . 2 . . . . 3 i2 0 0 . . . . 1 . . . . 2 . . . . 3 1 1 . . . . 2 . . . . 3 . . . . 4 2 1 . . . . 2 . . . . 3 . . . . 4 i1 3 2 . . . . 3 . . . . 4 . . . . 5 4 2 . . . . 3 . . . . 4 . . . . 5 5 3 . . . . 4 . . . . 5 . . . . 6 Fig.5: i1 depending on i1R and i2. */ void checkIndices(int i1, int j1, int ij1, int i1R, int j1R, int ij1R,int i2, int j2, int ij2,int frame, int i1max, int j1max, int i2max, int j2max, int i1Rmax, int j1Rmax) { if (i1<0) cout <<"ERROR : i1<0 !\n"; if (i1>=i1max) cout <<"ERROR : i1>=i1max !\n"; if (j1<0) cout <<"ERROR : j1<0 !\n"; if (j1>=j1max) cout <<"ERROR : j1>=j1max !\n"; if (ij1Index(i1,j1,j1max)!=ij1) cout <<"ERROR : ij1Index(i1,j1)!=ij1 !\n"; if (i1R<0) cout <<"ERROR : i1R<0 !\n"; if (i1R>=i1Rmax) cout <<"ERROR : i1R>=i1Rmax !\n"; if (j1R<0) cout <<"ERROR : j1R<0 !\n"; if (j1R>=j1Rmax) cout <<"ERROR : j1R>=j1Rmax !\n"; if (ij1RIndex(i1R,j1R,j1Rmax)!=ij1R) cout <<"ERROR : ij1RIndex(i1R,j1R)!=ij1R !\n"; if (i2<0) cout <<"ERROR : i2<0 !\n"; if (i2>=i2max) cout <<"ERROR : i2>=i2max !\n"; if (i1Index(i2,i1R,frame,i1max,i1Rmax,i2max)!=i1) cout <<"ERROR : i1Index(i2,i1R)!=i1 !\n"; if (j2<0) cout <<"ERROR : j2<0 !\n"; if (j2>=j2max) cout <<"ERROR : j2>=j2max !\n"; if (j1Index(j2,j1R,frame,j1max,j1Rmax,j2max)!=j1) cout <<"ERROR : j1Index(j2,j1R)!=j1 !\n"; if (ij2Index(i2,j2,j2max)!=ij2) cout <<"ERROR : ij2Index(i2,j2)!=ij2 !\n"; }