Mercurial > hg > camir-aes2014
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/MIRtoolbox1.3.2/somtoolbox/som_unit_dists.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,268 @@ +function Ud = som_unit_dists(topol,lattice,shape) + +%SOM_UNIT_DISTS Distances between unit-locations on the map grid. +% +% Ud = som_unit_dists(topol,[lattice],[shape]) +% +% Ud = som_unit_dists(sMap); +% Ud = som_unit_dists(sMap.topol); +% Ud = som_unit_dists(msize, 'hexa', 'cyl'); +% Ud = som_unit_dists([10 4 4], 'rect', 'toroid'); +% +% Input and output arguments ([]'s are optional): +% topol topology of the SOM grid +% (struct) topology or map struct +% (vector) the 'msize' field of topology struct +% [lattice] (string) map lattice, 'rect' by default +% [shape] (string) map shape, 'sheet' by default +% +% Ud (matrix, size [munits munits]) distance from each map unit +% to each map unit +% +% For more help, try 'type som_unit_dists' or check out online documentation. +% See also SOM_UNIT_COORDS, SOM_UNIT_NEIGHS. + +%%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% som_unit_dists +% +% PURPOSE +% +% Returns interunit distances between the units of a Self-Organizing Map +% along the map grid. +% +% SYNTAX +% +% Ud = som_unit_dists(sTopol); +% Ud = som_unit_dists(sM.topol); +% Ud = som_unit_dists(msize); +% Ud = som_unit_dists(msize,'hexa'); +% Ud = som_unit_dists(msize,'rect','toroid'); +% +% DESCRIPTION +% +% Calculates the distances between the units of a SOM based on the +% given topology. The distance are euclidian and they are measured +% along the map grid (in the output space). +% +% In case of 'sheet' shape, the distances can be measured directly +% from the unit coordinates given by SOM_UNIT_COORDS. +% +% In case of 'cyl' and 'toroid' shapes this is not so. In these cases +% the coordinates are calculated as in the case of 'sheet' shape and +% the shape is then taken into account by shifting the map grid into +% different positions. +% +% Consider, for example, a 4x3 map. The basic position of map units +% is shown on the left (with '1' - 'C' each denoting one map unit). +% In case of a 'cyl' shape, units on the left and right edges are +% neighbors, so for this purpose the map is copied on the left and +% right sides of the map, as on right. +% +% basic left basic right +% ------- ------- ------- ------- +% 1 5 9 1 5 9 1 5 9 1 5 9 +% 2 6 a 2 6 a 2 6 a 2 6 a +% 3 7 b 3 7 b 3 7 b 3 7 b +% 4 8 c 4 8 c 4 8 c 4 8 c +% +% For the 'toroid' shape a similar trick is done, except that the +% copies are placed all around the basic position: +% +% 1 5 9 1 5 9 1 5 9 +% 2 6 a 2 6 a 2 6 a +% 3 7 b 3 7 b 3 7 b +% 4 8 c 4 8 c 4 8 c +% 1 5 9 1 5 9 1 5 9 +% 2 6 a 2 6 a 2 6 a +% 3 7 b 3 7 b 3 7 b +% 4 8 c 4 8 c 4 8 c +% 1 5 9 1 5 9 1 5 9 +% 2 6 a 2 6 a 2 6 a +% 3 7 b 3 7 b 3 7 b +% 4 8 c 4 8 c 4 8 c +% +% From this we can see that the distance from unit '1' is 1 to units +% '9','2','4' and '5', and sqrt(2) to units 'C','A','8' and '6'. Notice +% that in the case of a 'hexa' lattice and 'toroid' shape, the size +% of the map in y-direction should be even. The reason can be clearly +% seen from the two figures below. On the left the basic positions for +% a 3x3 map. If the map is copied above itself, it can be seen that the +% lattice is broken (on the right): +% +% basic positions example of broken lattice +% --------------- ------------------------- +% 1 4 7 +% 2 5 8 +% 3 6 9 +% 1 4 7 1 4 7 +% 2 5 8 2 5 8 +% 3 6 9 3 6 9 +% +% +% REQUIRED INPUT ARGUMENTS +% +% topol Map grid dimensions. +% (struct) topology struct or map struct, the topology +% (msize, lattice, shape) of the map is taken from +% the appropriate fields (see e.g. SOM_SET) +% (vector) the vector which gives the size of the map grid +% (msize-field of the topology struct). +% +% OPTIONAL INPUT ARGUMENTS +% +% lattice (string) The map lattice, either 'rect' or 'hexa'. Default +% is 'rect'. 'hexa' can only be used with 1- or +% 2-dimensional map grids. +% shape (string) The map shape, either 'sheet', 'cyl' or 'toroid'. +% Default is 'sheet'. +% +% OUTPUT ARGUMENTS +% +% Ud (matrix) distances from each map unit to each other map unit, +% size is [munits munits] +% +% EXAMPLES +% +% Simplest case: +% Ud = som_unit_dists(sTopol); +% Ud = som_unit_dists(sMap.topol); +% Ud = som_unit_dists(msize); +% Ud = som_unit_dists([10 10]); +% +% If topology is given as vector, lattice is 'rect' and shape is 'sheet' +% by default. To change these, you can use the optional arguments: +% Ud = som_unit_dists(msize, 'hexa', 'toroid'); +% +% The distances can also be calculated for high-dimensional grids: +% Ud = som_unit_dists([4 4 4 4 4 4]); +% +% SEE ALSO +% +% som_unit_coords Calculate grid coordinates. +% som_unit_neighs Calculate neighborhoods of map units. + +% Copyright (c) 1997-2000 by the SOM toolbox programming team. +% http://www.cis.hut.fi/projects/somtoolbox/ + +% Version 1.0beta juuso 110997 +% Version 2.0beta juuso 101199 170400 070600 130600 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Check arguments + +error(nargchk(1, 3, nargin)); + +% default values +sTopol = som_set('som_topol','lattice','rect'); + +% topol +if isstruct(topol), + switch topol.type, + case 'som_map', sTopol = topol.topol; + case 'som_topol', sTopol = topol; + end +elseif iscell(topol), + for i=1:length(topol), + if isnumeric(topol{i}), sTopol.msize = topol{i}; + elseif ischar(topol{i}), + switch topol{i}, + case {'rect','hexa'}, sTopol.lattice = topol{i}; + case {'sheet','cyl','toroid'}, sTopol.shape = topol{i}; + end + end + end +else + sTopol.msize = topol; +end +if prod(sTopol.msize)==0, error('Map size is 0.'); end + +% lattice +if nargin>1 & ~isempty(lattice) & ~isnan(lattice), sTopol.lattice = lattice; end + +% shape +if nargin>2 & ~isempty(shape) & ~isnan(shape), sTopol.shape = shape; end + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Action + +msize = sTopol.msize; +lattice = sTopol.lattice; +shape = sTopol.shape; + +munits = prod(msize); +Ud = zeros(munits,munits); + +% free topology +if strcmp(lattice,'free'), + N1 = sTopol.connection; + Ud = som_neighborhood(N1,Inf); +end + +% coordinates of map units when the grid is spread on a plane +Coords = som_unit_coords(msize,lattice,'sheet'); + +% width and height of the grid +dx = max(Coords(:,1))-min(Coords(:,1)); +if msize(1)>1, dx = dx*msize(1)/(msize(1)-1); else dx = dx+1; end +dy = max(Coords(:,2))-min(Coords(:,2)); +if msize(2)>1, dy = dy*msize(2)/(msize(2)-1); else dy = dy+1; end + +% calculate distance from each location to each other location +switch shape, +case 'sheet', + for i=1:(munits-1), + inds = [(i+1):munits]; + Dco = (Coords(inds,:) - Coords(ones(munits-i,1)*i,:))'; + Ud(i,inds) = sqrt(sum(Dco.^2)); + end + +case 'cyl', + for i=1:(munits-1), + inds = [(i+1):munits]; + Dco = (Coords(inds,:) - Coords(ones(munits-i,1)*i,:))'; + dist = sum(Dco.^2); + % The cylinder shape is taken into account by adding and substracting + % the width of the map (dx) from the x-coordinate (ie. shifting the + % map right and left). + DcoS = Dco; DcoS(1,:) = DcoS(1,:) + dx; %East (x+dx) + dist = min(dist,sum(DcoS.^2)); + DcoS = Dco; DcoS(1,:) = DcoS(1,:) - dx; %West (x-dx) + dist = min(dist,sum(DcoS.^2)); + Ud(i,inds) = sqrt(dist); + end + +case 'toroid', + for i=1:(munits-1), + inds = [(i+1):munits]; + Dco = (Coords(inds,:) - Coords(ones(munits-i,1)*i,:))'; + dist = sum(Dco.^2); + % The toroid shape is taken into account as the cylinder shape was + % (see above), except that the map is shifted also vertically. + DcoS = Dco; DcoS(1,:) = DcoS(1,:) + dx; %East (x+dx) + dist = min(dist,sum(DcoS.^2)); + DcoS = Dco; DcoS(1,:) = DcoS(1,:) - dx; %West (x+dx) + dist = min(dist,sum(DcoS.^2)); + DcoS = Dco; DcoS(2,:) = DcoS(2,:) + dy; %South (y+dy) + dist = min(dist,sum(DcoS.^2)); + DcoS = Dco; DcoS(2,:) = DcoS(2,:) - dy; %North (y-dy) + dist = min(dist,sum(DcoS.^2)); + DcoS = Dco; DcoS(1,:) = DcoS(1,:) + dx; DcoS(2,:) = DcoS(2,:) - dy; %NorthEast (x+dx, y-dy) + dist = min(dist,sum(DcoS.^2)); + DcoS = Dco; DcoS(1,:) = DcoS(1,:) + dx; DcoS(2,:) = DcoS(2,:) + dy; %SouthEast (x+dx, y+dy) + dist = min(dist,sum(DcoS.^2)); + DcoS = Dco; DcoS(1,:) = DcoS(1,:) - dx; DcoS(2,:) = DcoS(2,:) + dy; %SouthWest (x-dx, y+dy) + dist = min(dist,sum(DcoS.^2)); + DcoS = Dco; DcoS(1,:) = DcoS(1,:) - dx; DcoS(2,:) = DcoS(2,:) - dy; %NorthWest (x-dx, y-dy) + dist = min(dist,sum(DcoS.^2)); + Ud(i,inds) = sqrt(dist); + end + +otherwise, + error (['Unknown shape: ', shape]); + +end + +Ud = Ud + Ud'; + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%