Mercurial > hg > camir-aes2014
comparison toolboxes/MIRtoolbox1.3.2/somtoolbox/som_unit_coords.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 function Coords = som_unit_coords(topol,lattice,shape) | |
2 | |
3 %SOM_UNIT_COORDS Locations of units on the SOM grid. | |
4 % | |
5 % Co = som_unit_coords(topol, [lattice], [shape]) | |
6 % | |
7 % Co = som_unit_coords(sMap); | |
8 % Co = som_unit_coords(sMap.topol); | |
9 % Co = som_unit_coords(msize, 'hexa', 'cyl'); | |
10 % Co = som_unit_coords([10 4 4], 'rect', 'toroid'); | |
11 % | |
12 % Input and output arguments ([]'s are optional): | |
13 % topol topology of the SOM grid | |
14 % (struct) topology or map struct | |
15 % (vector) the 'msize' field of topology struct | |
16 % [lattice] (string) map lattice, 'rect' by default | |
17 % [shape] (string) map shape, 'sheet' by default | |
18 % | |
19 % Co (matrix, size [munits k]) coordinates for each map unit | |
20 % | |
21 % For more help, try 'type som_unit_coords' or check out online documentation. | |
22 % See also SOM_UNIT_DISTS, SOM_UNIT_NEIGHS. | |
23 | |
24 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
25 % | |
26 % som_unit_coords | |
27 % | |
28 % PURPOSE | |
29 % | |
30 % Returns map grid coordinates for the units of a Self-Organizing Map. | |
31 % | |
32 % SYNTAX | |
33 % | |
34 % Co = som_unit_coords(sTopol); | |
35 % Co = som_unit_coords(sM.topol); | |
36 % Co = som_unit_coords(msize); | |
37 % Co = som_unit_coords(msize,'hexa'); | |
38 % Co = som_unit_coords(msize,'rect','toroid'); | |
39 % | |
40 % DESCRIPTION | |
41 % | |
42 % Calculates the map grid coordinates of the units of a SOM based on | |
43 % the given topology. The coordinates are such that they can be used to | |
44 % position map units in space. In case of 'sheet' shape they can be | |
45 % (and are) used to measure interunit distances. | |
46 % | |
47 % NOTE: for 'hexa' lattice, the x-coordinates of every other row are shifted | |
48 % by +0.5, and the y-coordinates are multiplied by sqrt(0.75). This is done | |
49 % to make distances of a unit to all its six neighbors equal. It is not | |
50 % possible to use 'hexa' lattice with higher than 2-dimensional map grids. | |
51 % | |
52 % 'cyl' and 'toroid' shapes: the coordinates are initially determined as | |
53 % in case of 'sheet' shape, but are then bended around the x- or the | |
54 % x- and then y-axes to get the desired shape. | |
55 % | |
56 % POSSIBLE BUGS | |
57 % | |
58 % I don't know if the bending operation works ok for high-dimensional | |
59 % map grids. Anyway, if anyone wants to make a 4-dimensional | |
60 % toroid map, (s)he deserves it. | |
61 % | |
62 % REQUIRED INPUT ARGUMENTS | |
63 % | |
64 % topol Map grid dimensions. | |
65 % (struct) topology struct or map struct, the topology | |
66 % (msize, lattice, shape) of the map is taken from | |
67 % the appropriate fields (see e.g. SOM_SET) | |
68 % (vector) the vector which gives the size of the map grid | |
69 % (msize-field of the topology struct). | |
70 % | |
71 % OPTIONAL INPUT ARGUMENTS | |
72 % | |
73 % lattice (string) The map lattice, either 'rect' or 'hexa'. Default | |
74 % is 'rect'. 'hexa' can only be used with 1- or | |
75 % 2-dimensional map grids. | |
76 % shape (string) The map shape, either 'sheet', 'cyl' or 'toroid'. | |
77 % Default is 'sheet'. | |
78 % | |
79 % OUTPUT ARGUMENTS | |
80 % | |
81 % Co (matrix) coordinates for each map units, size is [munits k] | |
82 % where k is 2, or more if the map grid is higher | |
83 % dimensional or the shape is 'cyl' or 'toroid' | |
84 % | |
85 % EXAMPLES | |
86 % | |
87 % Simplest case: | |
88 % Co = som_unit_coords(sTopol); | |
89 % Co = som_unit_coords(sMap.topol); | |
90 % Co = som_unit_coords(msize); | |
91 % Co = som_unit_coords([10 10]); | |
92 % | |
93 % If topology is given as vector, lattice is 'rect' and shape is 'sheet' | |
94 % by default. To change these, you can use the optional arguments: | |
95 % Co = som_unit_coords(msize, 'hexa', 'toroid'); | |
96 % | |
97 % The coordinates can also be calculated for high-dimensional grids: | |
98 % Co = som_unit_coords([4 4 4 4 4 4]); | |
99 % | |
100 % SEE ALSO | |
101 % | |
102 % som_unit_dists Calculate interunit distance along the map grid. | |
103 % som_unit_neighs Calculate neighborhoods of map units. | |
104 | |
105 % Copyright (c) 1997-2000 by the SOM toolbox programming team. | |
106 % http://www.cis.hut.fi/projects/somtoolbox/ | |
107 | |
108 % Version 1.0beta juuso 110997 | |
109 % Version 2.0beta juuso 101199 070600 | |
110 | |
111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
112 %% Check arguments | |
113 | |
114 error(nargchk(1, 3, nargin)); | |
115 | |
116 % default values | |
117 sTopol = som_set('som_topol','lattice','rect'); | |
118 | |
119 % topol | |
120 if isstruct(topol), | |
121 switch topol.type, | |
122 case 'som_map', sTopol = topol.topol; | |
123 case 'som_topol', sTopol = topol; | |
124 end | |
125 elseif iscell(topol), | |
126 for i=1:length(topol), | |
127 if isnumeric(topol{i}), sTopol.msize = topol{i}; | |
128 elseif ischar(topol{i}), | |
129 switch topol{i}, | |
130 case {'rect','hexa'}, sTopol.lattice = topol{i}; | |
131 case {'sheet','cyl','toroid'}, sTopol.shape = topol{i}; | |
132 end | |
133 end | |
134 end | |
135 else | |
136 sTopol.msize = topol; | |
137 end | |
138 if prod(sTopol.msize)==0, error('Map size is 0.'); end | |
139 | |
140 % lattice | |
141 if nargin>1 & ~isempty(lattice) & ~isnan(lattice), sTopol.lattice = lattice; end | |
142 | |
143 % shape | |
144 if nargin>2 & ~isempty(shape) & ~isnan(shape), sTopol.shape = shape; end | |
145 | |
146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
147 %% Action | |
148 | |
149 msize = sTopol.msize; | |
150 lattice = sTopol.lattice; | |
151 shape = sTopol.shape; | |
152 | |
153 % init variables | |
154 | |
155 if length(msize)==1, msize = [msize 1]; end | |
156 munits = prod(msize); | |
157 mdim = length(msize); | |
158 Coords = zeros(munits,mdim); | |
159 | |
160 % initial coordinates for each map unit ('rect' lattice, 'sheet' shape) | |
161 k = [1 cumprod(msize(1:end-1))]; | |
162 inds = [0:(munits-1)]'; | |
163 for i = mdim:-1:1, | |
164 Coords(:,i) = floor(inds/k(i)); % these are subscripts in matrix-notation | |
165 inds = rem(inds,k(i)); | |
166 end | |
167 % change subscripts to coordinates (move from (ij)-notation to (xy)-notation) | |
168 Coords(:,[1 2]) = fliplr(Coords(:,[1 2])); | |
169 | |
170 % 'hexa' lattice | |
171 if strcmp(lattice,'hexa'), | |
172 % check | |
173 if mdim > 2, | |
174 error('You can only use hexa lattice with 1- or 2-dimensional maps.'); | |
175 end | |
176 % offset x-coordinates of every other row | |
177 inds_for_row = (cumsum(ones(msize(2),1))-1)*msize(1); | |
178 for i=2:2:msize(1), | |
179 Coords(i+inds_for_row,1) = Coords(i+inds_for_row,1) + 0.5; | |
180 end | |
181 end | |
182 | |
183 % shapes | |
184 switch shape, | |
185 case 'sheet', | |
186 if strcmp(lattice,'hexa'), | |
187 % this correction is made to make distances to all | |
188 % neighboring units equal | |
189 Coords(:,2) = Coords(:,2)*sqrt(0.75); | |
190 end | |
191 | |
192 case 'cyl', | |
193 % to make cylinder the coordinates must lie in 3D space, at least | |
194 if mdim<3, Coords = [Coords ones(munits,1)]; mdim = 3; end | |
195 | |
196 % Bend the coordinates to a circle in the plane formed by x- and | |
197 % and z-axis. Notice that the angle to which the last coordinates | |
198 % are bended is _not_ 360 degrees, because that would be equal to | |
199 % the angle of the first coordinates (0 degrees). | |
200 | |
201 Coords(:,1) = Coords(:,1)/max(Coords(:,1)); | |
202 Coords(:,1) = 2*pi * Coords(:,1) * msize(2)/(msize(2)+1); | |
203 Coords(:,[1 3]) = [cos(Coords(:,1)) sin(Coords(:,1))]; | |
204 | |
205 case 'toroid', | |
206 | |
207 % NOTE: if lattice is 'hexa', the msize(1) should be even, otherwise | |
208 % the bending the upper and lower edges of the map do not match | |
209 % to each other | |
210 if strcmp(lattice,'hexa') & rem(msize(1),2)==1, | |
211 warning('Map size along y-coordinate is not even.'); | |
212 end | |
213 | |
214 % to make toroid the coordinates must lie in 3D space, at least | |
215 if mdim<3, Coords = [Coords ones(munits,1)]; mdim = 3; end | |
216 | |
217 % First bend the coordinates to a circle in the plane formed | |
218 % by x- and z-axis. Then bend in the plane formed by y- and | |
219 % z-axis. (See also the notes in 'cyl'). | |
220 | |
221 Coords(:,1) = Coords(:,1)/max(Coords(:,1)); | |
222 Coords(:,1) = 2*pi * Coords(:,1) * msize(2)/(msize(2)+1); | |
223 Coords(:,[1 3]) = [cos(Coords(:,1)) sin(Coords(:,1))]; | |
224 | |
225 Coords(:,2) = Coords(:,2)/max(Coords(:,2)); | |
226 Coords(:,2) = 2*pi * Coords(:,2) * msize(1)/(msize(1)+1); | |
227 Coords(:,3) = Coords(:,3) - min(Coords(:,3)) + 1; | |
228 Coords(:,[2 3]) = Coords(:,[3 3]) .* [cos(Coords(:,2)) sin(Coords(:,2))]; | |
229 | |
230 end | |
231 | |
232 return; | |
233 | |
234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
235 %% subfunctions | |
236 | |
237 function C = bend(cx,cy,angle,xishexa) | |
238 | |
239 dx = max(cx) - min(cx); | |
240 if dx ~= 0, | |
241 % in case of hexagonal lattice it must be taken into account that | |
242 % coordinates of every second row are +0.5 off to the right | |
243 if xishexa, dx = dx-0.5; end | |
244 cx = angle*(cx - min(cx))/dx; | |
245 end | |
246 C(:,1) = (cy - min(cy)+1) .* cos(cx); | |
247 C(:,2) = (cy - min(cy)+1) .* sin(cx); | |
248 | |
249 % end of bend | |
250 | |
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
252 |