annotate toolboxes/MIRtoolbox1.3.2/somtoolbox/som_unit_dists.m @ 0:e9a9cd732c1e tip

first hg version after svn
author wolffd
date Tue, 10 Feb 2015 15:05:51 +0000
parents
children
rev   line source
wolffd@0 1 function Ud = som_unit_dists(topol,lattice,shape)
wolffd@0 2
wolffd@0 3 %SOM_UNIT_DISTS Distances between unit-locations on the map grid.
wolffd@0 4 %
wolffd@0 5 % Ud = som_unit_dists(topol,[lattice],[shape])
wolffd@0 6 %
wolffd@0 7 % Ud = som_unit_dists(sMap);
wolffd@0 8 % Ud = som_unit_dists(sMap.topol);
wolffd@0 9 % Ud = som_unit_dists(msize, 'hexa', 'cyl');
wolffd@0 10 % Ud = som_unit_dists([10 4 4], 'rect', 'toroid');
wolffd@0 11 %
wolffd@0 12 % Input and output arguments ([]'s are optional):
wolffd@0 13 % topol topology of the SOM grid
wolffd@0 14 % (struct) topology or map struct
wolffd@0 15 % (vector) the 'msize' field of topology struct
wolffd@0 16 % [lattice] (string) map lattice, 'rect' by default
wolffd@0 17 % [shape] (string) map shape, 'sheet' by default
wolffd@0 18 %
wolffd@0 19 % Ud (matrix, size [munits munits]) distance from each map unit
wolffd@0 20 % to each map unit
wolffd@0 21 %
wolffd@0 22 % For more help, try 'type som_unit_dists' or check out online documentation.
wolffd@0 23 % See also SOM_UNIT_COORDS, SOM_UNIT_NEIGHS.
wolffd@0 24
wolffd@0 25 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 26 %
wolffd@0 27 % som_unit_dists
wolffd@0 28 %
wolffd@0 29 % PURPOSE
wolffd@0 30 %
wolffd@0 31 % Returns interunit distances between the units of a Self-Organizing Map
wolffd@0 32 % along the map grid.
wolffd@0 33 %
wolffd@0 34 % SYNTAX
wolffd@0 35 %
wolffd@0 36 % Ud = som_unit_dists(sTopol);
wolffd@0 37 % Ud = som_unit_dists(sM.topol);
wolffd@0 38 % Ud = som_unit_dists(msize);
wolffd@0 39 % Ud = som_unit_dists(msize,'hexa');
wolffd@0 40 % Ud = som_unit_dists(msize,'rect','toroid');
wolffd@0 41 %
wolffd@0 42 % DESCRIPTION
wolffd@0 43 %
wolffd@0 44 % Calculates the distances between the units of a SOM based on the
wolffd@0 45 % given topology. The distance are euclidian and they are measured
wolffd@0 46 % along the map grid (in the output space).
wolffd@0 47 %
wolffd@0 48 % In case of 'sheet' shape, the distances can be measured directly
wolffd@0 49 % from the unit coordinates given by SOM_UNIT_COORDS.
wolffd@0 50 %
wolffd@0 51 % In case of 'cyl' and 'toroid' shapes this is not so. In these cases
wolffd@0 52 % the coordinates are calculated as in the case of 'sheet' shape and
wolffd@0 53 % the shape is then taken into account by shifting the map grid into
wolffd@0 54 % different positions.
wolffd@0 55 %
wolffd@0 56 % Consider, for example, a 4x3 map. The basic position of map units
wolffd@0 57 % is shown on the left (with '1' - 'C' each denoting one map unit).
wolffd@0 58 % In case of a 'cyl' shape, units on the left and right edges are
wolffd@0 59 % neighbors, so for this purpose the map is copied on the left and
wolffd@0 60 % right sides of the map, as on right.
wolffd@0 61 %
wolffd@0 62 % basic left basic right
wolffd@0 63 % ------- ------- ------- -------
wolffd@0 64 % 1 5 9 1 5 9 1 5 9 1 5 9
wolffd@0 65 % 2 6 a 2 6 a 2 6 a 2 6 a
wolffd@0 66 % 3 7 b 3 7 b 3 7 b 3 7 b
wolffd@0 67 % 4 8 c 4 8 c 4 8 c 4 8 c
wolffd@0 68 %
wolffd@0 69 % For the 'toroid' shape a similar trick is done, except that the
wolffd@0 70 % copies are placed all around the basic position:
wolffd@0 71 %
wolffd@0 72 % 1 5 9 1 5 9 1 5 9
wolffd@0 73 % 2 6 a 2 6 a 2 6 a
wolffd@0 74 % 3 7 b 3 7 b 3 7 b
wolffd@0 75 % 4 8 c 4 8 c 4 8 c
wolffd@0 76 % 1 5 9 1 5 9 1 5 9
wolffd@0 77 % 2 6 a 2 6 a 2 6 a
wolffd@0 78 % 3 7 b 3 7 b 3 7 b
wolffd@0 79 % 4 8 c 4 8 c 4 8 c
wolffd@0 80 % 1 5 9 1 5 9 1 5 9
wolffd@0 81 % 2 6 a 2 6 a 2 6 a
wolffd@0 82 % 3 7 b 3 7 b 3 7 b
wolffd@0 83 % 4 8 c 4 8 c 4 8 c
wolffd@0 84 %
wolffd@0 85 % From this we can see that the distance from unit '1' is 1 to units
wolffd@0 86 % '9','2','4' and '5', and sqrt(2) to units 'C','A','8' and '6'. Notice
wolffd@0 87 % that in the case of a 'hexa' lattice and 'toroid' shape, the size
wolffd@0 88 % of the map in y-direction should be even. The reason can be clearly
wolffd@0 89 % seen from the two figures below. On the left the basic positions for
wolffd@0 90 % a 3x3 map. If the map is copied above itself, it can be seen that the
wolffd@0 91 % lattice is broken (on the right):
wolffd@0 92 %
wolffd@0 93 % basic positions example of broken lattice
wolffd@0 94 % --------------- -------------------------
wolffd@0 95 % 1 4 7
wolffd@0 96 % 2 5 8
wolffd@0 97 % 3 6 9
wolffd@0 98 % 1 4 7 1 4 7
wolffd@0 99 % 2 5 8 2 5 8
wolffd@0 100 % 3 6 9 3 6 9
wolffd@0 101 %
wolffd@0 102 %
wolffd@0 103 % REQUIRED INPUT ARGUMENTS
wolffd@0 104 %
wolffd@0 105 % topol Map grid dimensions.
wolffd@0 106 % (struct) topology struct or map struct, the topology
wolffd@0 107 % (msize, lattice, shape) of the map is taken from
wolffd@0 108 % the appropriate fields (see e.g. SOM_SET)
wolffd@0 109 % (vector) the vector which gives the size of the map grid
wolffd@0 110 % (msize-field of the topology struct).
wolffd@0 111 %
wolffd@0 112 % OPTIONAL INPUT ARGUMENTS
wolffd@0 113 %
wolffd@0 114 % lattice (string) The map lattice, either 'rect' or 'hexa'. Default
wolffd@0 115 % is 'rect'. 'hexa' can only be used with 1- or
wolffd@0 116 % 2-dimensional map grids.
wolffd@0 117 % shape (string) The map shape, either 'sheet', 'cyl' or 'toroid'.
wolffd@0 118 % Default is 'sheet'.
wolffd@0 119 %
wolffd@0 120 % OUTPUT ARGUMENTS
wolffd@0 121 %
wolffd@0 122 % Ud (matrix) distances from each map unit to each other map unit,
wolffd@0 123 % size is [munits munits]
wolffd@0 124 %
wolffd@0 125 % EXAMPLES
wolffd@0 126 %
wolffd@0 127 % Simplest case:
wolffd@0 128 % Ud = som_unit_dists(sTopol);
wolffd@0 129 % Ud = som_unit_dists(sMap.topol);
wolffd@0 130 % Ud = som_unit_dists(msize);
wolffd@0 131 % Ud = som_unit_dists([10 10]);
wolffd@0 132 %
wolffd@0 133 % If topology is given as vector, lattice is 'rect' and shape is 'sheet'
wolffd@0 134 % by default. To change these, you can use the optional arguments:
wolffd@0 135 % Ud = som_unit_dists(msize, 'hexa', 'toroid');
wolffd@0 136 %
wolffd@0 137 % The distances can also be calculated for high-dimensional grids:
wolffd@0 138 % Ud = som_unit_dists([4 4 4 4 4 4]);
wolffd@0 139 %
wolffd@0 140 % SEE ALSO
wolffd@0 141 %
wolffd@0 142 % som_unit_coords Calculate grid coordinates.
wolffd@0 143 % som_unit_neighs Calculate neighborhoods of map units.
wolffd@0 144
wolffd@0 145 % Copyright (c) 1997-2000 by the SOM toolbox programming team.
wolffd@0 146 % http://www.cis.hut.fi/projects/somtoolbox/
wolffd@0 147
wolffd@0 148 % Version 1.0beta juuso 110997
wolffd@0 149 % Version 2.0beta juuso 101199 170400 070600 130600
wolffd@0 150
wolffd@0 151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 152 %% Check arguments
wolffd@0 153
wolffd@0 154 error(nargchk(1, 3, nargin));
wolffd@0 155
wolffd@0 156 % default values
wolffd@0 157 sTopol = som_set('som_topol','lattice','rect');
wolffd@0 158
wolffd@0 159 % topol
wolffd@0 160 if isstruct(topol),
wolffd@0 161 switch topol.type,
wolffd@0 162 case 'som_map', sTopol = topol.topol;
wolffd@0 163 case 'som_topol', sTopol = topol;
wolffd@0 164 end
wolffd@0 165 elseif iscell(topol),
wolffd@0 166 for i=1:length(topol),
wolffd@0 167 if isnumeric(topol{i}), sTopol.msize = topol{i};
wolffd@0 168 elseif ischar(topol{i}),
wolffd@0 169 switch topol{i},
wolffd@0 170 case {'rect','hexa'}, sTopol.lattice = topol{i};
wolffd@0 171 case {'sheet','cyl','toroid'}, sTopol.shape = topol{i};
wolffd@0 172 end
wolffd@0 173 end
wolffd@0 174 end
wolffd@0 175 else
wolffd@0 176 sTopol.msize = topol;
wolffd@0 177 end
wolffd@0 178 if prod(sTopol.msize)==0, error('Map size is 0.'); end
wolffd@0 179
wolffd@0 180 % lattice
wolffd@0 181 if nargin>1 & ~isempty(lattice) & ~isnan(lattice), sTopol.lattice = lattice; end
wolffd@0 182
wolffd@0 183 % shape
wolffd@0 184 if nargin>2 & ~isempty(shape) & ~isnan(shape), sTopol.shape = shape; end
wolffd@0 185
wolffd@0 186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wolffd@0 187 %% Action
wolffd@0 188
wolffd@0 189 msize = sTopol.msize;
wolffd@0 190 lattice = sTopol.lattice;
wolffd@0 191 shape = sTopol.shape;
wolffd@0 192
wolffd@0 193 munits = prod(msize);
wolffd@0 194 Ud = zeros(munits,munits);
wolffd@0 195
wolffd@0 196 % free topology
wolffd@0 197 if strcmp(lattice,'free'),
wolffd@0 198 N1 = sTopol.connection;
wolffd@0 199 Ud = som_neighborhood(N1,Inf);
wolffd@0 200 end
wolffd@0 201
wolffd@0 202 % coordinates of map units when the grid is spread on a plane
wolffd@0 203 Coords = som_unit_coords(msize,lattice,'sheet');
wolffd@0 204
wolffd@0 205 % width and height of the grid
wolffd@0 206 dx = max(Coords(:,1))-min(Coords(:,1));
wolffd@0 207 if msize(1)>1, dx = dx*msize(1)/(msize(1)-1); else dx = dx+1; end
wolffd@0 208 dy = max(Coords(:,2))-min(Coords(:,2));
wolffd@0 209 if msize(2)>1, dy = dy*msize(2)/(msize(2)-1); else dy = dy+1; end
wolffd@0 210
wolffd@0 211 % calculate distance from each location to each other location
wolffd@0 212 switch shape,
wolffd@0 213 case 'sheet',
wolffd@0 214 for i=1:(munits-1),
wolffd@0 215 inds = [(i+1):munits];
wolffd@0 216 Dco = (Coords(inds,:) - Coords(ones(munits-i,1)*i,:))';
wolffd@0 217 Ud(i,inds) = sqrt(sum(Dco.^2));
wolffd@0 218 end
wolffd@0 219
wolffd@0 220 case 'cyl',
wolffd@0 221 for i=1:(munits-1),
wolffd@0 222 inds = [(i+1):munits];
wolffd@0 223 Dco = (Coords(inds,:) - Coords(ones(munits-i,1)*i,:))';
wolffd@0 224 dist = sum(Dco.^2);
wolffd@0 225 % The cylinder shape is taken into account by adding and substracting
wolffd@0 226 % the width of the map (dx) from the x-coordinate (ie. shifting the
wolffd@0 227 % map right and left).
wolffd@0 228 DcoS = Dco; DcoS(1,:) = DcoS(1,:) + dx; %East (x+dx)
wolffd@0 229 dist = min(dist,sum(DcoS.^2));
wolffd@0 230 DcoS = Dco; DcoS(1,:) = DcoS(1,:) - dx; %West (x-dx)
wolffd@0 231 dist = min(dist,sum(DcoS.^2));
wolffd@0 232 Ud(i,inds) = sqrt(dist);
wolffd@0 233 end
wolffd@0 234
wolffd@0 235 case 'toroid',
wolffd@0 236 for i=1:(munits-1),
wolffd@0 237 inds = [(i+1):munits];
wolffd@0 238 Dco = (Coords(inds,:) - Coords(ones(munits-i,1)*i,:))';
wolffd@0 239 dist = sum(Dco.^2);
wolffd@0 240 % The toroid shape is taken into account as the cylinder shape was
wolffd@0 241 % (see above), except that the map is shifted also vertically.
wolffd@0 242 DcoS = Dco; DcoS(1,:) = DcoS(1,:) + dx; %East (x+dx)
wolffd@0 243 dist = min(dist,sum(DcoS.^2));
wolffd@0 244 DcoS = Dco; DcoS(1,:) = DcoS(1,:) - dx; %West (x+dx)
wolffd@0 245 dist = min(dist,sum(DcoS.^2));
wolffd@0 246 DcoS = Dco; DcoS(2,:) = DcoS(2,:) + dy; %South (y+dy)
wolffd@0 247 dist = min(dist,sum(DcoS.^2));
wolffd@0 248 DcoS = Dco; DcoS(2,:) = DcoS(2,:) - dy; %North (y-dy)
wolffd@0 249 dist = min(dist,sum(DcoS.^2));
wolffd@0 250 DcoS = Dco; DcoS(1,:) = DcoS(1,:) + dx; DcoS(2,:) = DcoS(2,:) - dy; %NorthEast (x+dx, y-dy)
wolffd@0 251 dist = min(dist,sum(DcoS.^2));
wolffd@0 252 DcoS = Dco; DcoS(1,:) = DcoS(1,:) + dx; DcoS(2,:) = DcoS(2,:) + dy; %SouthEast (x+dx, y+dy)
wolffd@0 253 dist = min(dist,sum(DcoS.^2));
wolffd@0 254 DcoS = Dco; DcoS(1,:) = DcoS(1,:) - dx; DcoS(2,:) = DcoS(2,:) + dy; %SouthWest (x-dx, y+dy)
wolffd@0 255 dist = min(dist,sum(DcoS.^2));
wolffd@0 256 DcoS = Dco; DcoS(1,:) = DcoS(1,:) - dx; DcoS(2,:) = DcoS(2,:) - dy; %NorthWest (x-dx, y-dy)
wolffd@0 257 dist = min(dist,sum(DcoS.^2));
wolffd@0 258 Ud(i,inds) = sqrt(dist);
wolffd@0 259 end
wolffd@0 260
wolffd@0 261 otherwise,
wolffd@0 262 error (['Unknown shape: ', shape]);
wolffd@0 263
wolffd@0 264 end
wolffd@0 265
wolffd@0 266 Ud = Ud + Ud';
wolffd@0 267
wolffd@0 268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%