wolffd@0
|
1 function sMap = som_lininit(D, varargin)
|
wolffd@0
|
2
|
wolffd@0
|
3 %SOM_LININIT Initialize a Self-Organizing Map linearly.
|
wolffd@0
|
4 %
|
wolffd@0
|
5 % sMap = som_lininit(D, [[argID,] value, ...])
|
wolffd@0
|
6 %
|
wolffd@0
|
7 % sMap = som_lininit(D);
|
wolffd@0
|
8 % sMap = som_lininit(D,sMap);
|
wolffd@0
|
9 % sMap = som_lininit(D,'munits',100,'hexa');
|
wolffd@0
|
10 %
|
wolffd@0
|
11 % Input and output arguments ([]'s are optional):
|
wolffd@0
|
12 % D The training data.
|
wolffd@0
|
13 % (struct) data struct
|
wolffd@0
|
14 % (matrix) data matrix, size dlen x dim
|
wolffd@0
|
15 % [argID, (string) Parameters affecting the map topology are given
|
wolffd@0
|
16 % value] (varies) as argument ID - argument value pairs, listed below.
|
wolffd@0
|
17 % sMap (struct) map struct
|
wolffd@0
|
18 %
|
wolffd@0
|
19 % Here are the valid argument IDs and corresponding values. The values
|
wolffd@0
|
20 % which are unambiguous (marked with '*') can be given without the
|
wolffd@0
|
21 % preceeding argID.
|
wolffd@0
|
22 % 'munits' (scalar) number of map units
|
wolffd@0
|
23 % 'msize' (vector) map size
|
wolffd@0
|
24 % 'lattice' *(string) map lattice: 'hexa' or 'rect'
|
wolffd@0
|
25 % 'shape' *(string) map shape: 'sheet', 'cyl' or 'toroid'
|
wolffd@0
|
26 % 'topol' *(struct) topology struct
|
wolffd@0
|
27 % 'som_topol','sTopol' = 'topol'
|
wolffd@0
|
28 % 'map' *(struct) map struct
|
wolffd@0
|
29 % 'som_map','sMap' = 'map'
|
wolffd@0
|
30 %
|
wolffd@0
|
31 % For more help, try 'type som_lininit' or check out online documentation.
|
wolffd@0
|
32 % See also SOM_MAP_STRUCT, SOM_RANDINIT, SOM_MAKE.
|
wolffd@0
|
33
|
wolffd@0
|
34 %%%%%%%%%%%%% DETAILED DESCRIPTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
35 %
|
wolffd@0
|
36 % som_lininit
|
wolffd@0
|
37 %
|
wolffd@0
|
38 % PURPOSE
|
wolffd@0
|
39 %
|
wolffd@0
|
40 % Initializes a SOM linearly along its greatest eigenvectors.
|
wolffd@0
|
41 %
|
wolffd@0
|
42 % SYNTAX
|
wolffd@0
|
43 %
|
wolffd@0
|
44 % sMap = som_lininit(D);
|
wolffd@0
|
45 % sMap = som_lininit(D,sMap);
|
wolffd@0
|
46 % sMap = som_lininit(D,'munits',100,'hexa');
|
wolffd@0
|
47 %
|
wolffd@0
|
48 % DESCRIPTION
|
wolffd@0
|
49 %
|
wolffd@0
|
50 % Initializes a SOM linearly. If necessary, a map struct is created
|
wolffd@0
|
51 % first. The initialization is made by first calculating the eigenvalues
|
wolffd@0
|
52 % and eigenvectors of the training data. Then, the map is initialized
|
wolffd@0
|
53 % along the mdim greatest eigenvectors of the training data, where
|
wolffd@0
|
54 % mdim is the dimension of the map grid.
|
wolffd@0
|
55 %
|
wolffd@0
|
56 % REFERENCES
|
wolffd@0
|
57 %
|
wolffd@0
|
58 % Kohonen, T., "Self-Organizing Map", 2nd ed., Springer-Verlag,
|
wolffd@0
|
59 % Berlin, 1995, pp. 106-107.
|
wolffd@0
|
60 %
|
wolffd@0
|
61 % REQUIRED INPUT ARGUMENTS
|
wolffd@0
|
62 %
|
wolffd@0
|
63 % D The training data.
|
wolffd@0
|
64 % (struct) Data struct. If this is given, its '.comp_names' and
|
wolffd@0
|
65 % '.comp_norm' fields are copied to the map struct.
|
wolffd@0
|
66 % (matrix) data matrix, size dlen x dim
|
wolffd@0
|
67 %
|
wolffd@0
|
68 % OPTIONAL INPUT ARGUMENTS
|
wolffd@0
|
69 %
|
wolffd@0
|
70 % argID (string) Argument identifier string (see below).
|
wolffd@0
|
71 % value (varies) Value for the argument (see below).
|
wolffd@0
|
72 %
|
wolffd@0
|
73 % The optional arguments can be given as 'argID',value -pairs. If an
|
wolffd@0
|
74 % argument is given value multiple times, the last one is used.
|
wolffd@0
|
75 %
|
wolffd@0
|
76 % Here are the valid argument IDs and corresponding values. The values
|
wolffd@0
|
77 % which are unambiguous (marked with '*') can be given without the
|
wolffd@0
|
78 % preceeding argID.
|
wolffd@0
|
79 % 'dlen' (scalar) length of the training data
|
wolffd@0
|
80 % 'data' (matrix) the training data
|
wolffd@0
|
81 % *(struct) the training data
|
wolffd@0
|
82 % 'munits' (scalar) number of map units
|
wolffd@0
|
83 % 'msize' (vector) map size
|
wolffd@0
|
84 % 'lattice' *(string) map lattice: 'hexa' or 'rect'
|
wolffd@0
|
85 % 'shape' *(string) map shape: 'sheet', 'cyl' or 'toroid'
|
wolffd@0
|
86 % 'topol' *(struct) topology struct
|
wolffd@0
|
87 % 'som_topol','sTopol' = 'topol'
|
wolffd@0
|
88 % 'map' *(struct) map struct
|
wolffd@0
|
89 % 'som_map','sMap' = 'map'
|
wolffd@0
|
90 %
|
wolffd@0
|
91 % OUTPUT ARGUMENTS
|
wolffd@0
|
92 %
|
wolffd@0
|
93 % sMap (struct) The initialized map struct.
|
wolffd@0
|
94 %
|
wolffd@0
|
95 % EXAMPLES
|
wolffd@0
|
96 %
|
wolffd@0
|
97 % sMap = som_lininit(D);
|
wolffd@0
|
98 % sMap = som_lininit(D,sMap);
|
wolffd@0
|
99 % sMap = som_lininit(D,'msize',[10 10]);
|
wolffd@0
|
100 % sMap = som_lininit(D,'munits',100,'rect');
|
wolffd@0
|
101 %
|
wolffd@0
|
102 % SEE ALSO
|
wolffd@0
|
103 %
|
wolffd@0
|
104 % som_map_struct Create a map struct.
|
wolffd@0
|
105 % som_randinit Initialize a map with random values.
|
wolffd@0
|
106 % som_make Initialize and train self-organizing map.
|
wolffd@0
|
107
|
wolffd@0
|
108 % Copyright (c) 1997-2000 by the SOM toolbox programming team.
|
wolffd@0
|
109 % http://www.cis.hut.fi/projects/somtoolbox/
|
wolffd@0
|
110
|
wolffd@0
|
111 % Version 1.0beta ecco 100997
|
wolffd@0
|
112 % Version 2.0beta 101199
|
wolffd@0
|
113
|
wolffd@0
|
114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
115 %% check arguments
|
wolffd@0
|
116
|
wolffd@0
|
117 % data
|
wolffd@0
|
118 if isstruct(D),
|
wolffd@0
|
119 data_name = D.name;
|
wolffd@0
|
120 comp_names = D.comp_names;
|
wolffd@0
|
121 comp_norm = D.comp_norm;
|
wolffd@0
|
122 D = D.data;
|
wolffd@0
|
123 struct_mode = 1;
|
wolffd@0
|
124 else
|
wolffd@0
|
125 data_name = inputname(1);
|
wolffd@0
|
126 struct_mode = 0;
|
wolffd@0
|
127 end
|
wolffd@0
|
128 [dlen dim] = size(D);
|
wolffd@0
|
129
|
wolffd@0
|
130 % varargin
|
wolffd@0
|
131 sMap = [];
|
wolffd@0
|
132 sTopol = som_topol_struct;
|
wolffd@0
|
133 sTopol.msize = 0;
|
wolffd@0
|
134 munits = NaN;
|
wolffd@0
|
135 i=1;
|
wolffd@0
|
136 while i<=length(varargin),
|
wolffd@0
|
137 argok = 1;
|
wolffd@0
|
138 if ischar(varargin{i}),
|
wolffd@0
|
139 switch varargin{i},
|
wolffd@0
|
140 case 'munits', i=i+1; munits = varargin{i}; sTopol.msize = 0;
|
wolffd@0
|
141 case 'msize', i=i+1; sTopol.msize = varargin{i};
|
wolffd@0
|
142 munits = prod(sTopol.msize);
|
wolffd@0
|
143 case 'lattice', i=i+1; sTopol.lattice = varargin{i};
|
wolffd@0
|
144 case 'shape', i=i+1; sTopol.shape = varargin{i};
|
wolffd@0
|
145 case {'som_topol','sTopol','topol'}, i=i+1; sTopol = varargin{i};
|
wolffd@0
|
146 case {'som_map','sMap','map'}, i=i+1; sMap = varargin{i}; sTopol = sMap.topol;
|
wolffd@0
|
147 case {'hexa','rect'}, sTopol.lattice = varargin{i};
|
wolffd@0
|
148 case {'sheet','cyl','toroid'}, sTopol.shape = varargin{i};
|
wolffd@0
|
149 otherwise argok=0;
|
wolffd@0
|
150 end
|
wolffd@0
|
151 elseif isstruct(varargin{i}) & isfield(varargin{i},'type'),
|
wolffd@0
|
152 switch varargin{i}.type,
|
wolffd@0
|
153 case 'som_topol',
|
wolffd@0
|
154 sTopol = varargin{i};
|
wolffd@0
|
155 case 'som_map',
|
wolffd@0
|
156 sMap = varargin{i};
|
wolffd@0
|
157 sTopol = sMap.topol;
|
wolffd@0
|
158 otherwise argok=0;
|
wolffd@0
|
159 end
|
wolffd@0
|
160 else
|
wolffd@0
|
161 argok = 0;
|
wolffd@0
|
162 end
|
wolffd@0
|
163 if ~argok,
|
wolffd@0
|
164 disp(['(som_topol_struct) Ignoring invalid argument #' num2str(i)]);
|
wolffd@0
|
165 end
|
wolffd@0
|
166 i = i+1;
|
wolffd@0
|
167 end
|
wolffd@0
|
168
|
wolffd@0
|
169 if length(sTopol.msize)==1, sTopol.msize = [sTopol.msize 1]; end
|
wolffd@0
|
170
|
wolffd@0
|
171 if ~isempty(sMap),
|
wolffd@0
|
172 [munits dim2] = size(sMap.codebook);
|
wolffd@0
|
173 if dim2 ~= dim, error('Map and data must have the same dimension.'); end
|
wolffd@0
|
174 end
|
wolffd@0
|
175
|
wolffd@0
|
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
177 %% create map
|
wolffd@0
|
178
|
wolffd@0
|
179 % map struct
|
wolffd@0
|
180 if ~isempty(sMap),
|
wolffd@0
|
181 sMap = som_set(sMap,'topol',sTopol);
|
wolffd@0
|
182 else
|
wolffd@0
|
183 if ~prod(sTopol.msize),
|
wolffd@0
|
184 if isnan(munits),
|
wolffd@0
|
185 sTopol = som_topol_struct('data',D,sTopol);
|
wolffd@0
|
186 else
|
wolffd@0
|
187 sTopol = som_topol_struct('data',D,'munits',munits,sTopol);
|
wolffd@0
|
188 end
|
wolffd@0
|
189 end
|
wolffd@0
|
190 sMap = som_map_struct(dim, sTopol);
|
wolffd@0
|
191 end
|
wolffd@0
|
192
|
wolffd@0
|
193 if struct_mode,
|
wolffd@0
|
194 sMap = som_set(sMap,'comp_names',comp_names,'comp_norm',comp_norm);
|
wolffd@0
|
195 end
|
wolffd@0
|
196
|
wolffd@0
|
197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
wolffd@0
|
198 %% initialization
|
wolffd@0
|
199
|
wolffd@0
|
200 % train struct
|
wolffd@0
|
201 sTrain = som_train_struct('algorithm','lininit');
|
wolffd@0
|
202 sTrain = som_set(sTrain,'data_name',data_name);
|
wolffd@0
|
203
|
wolffd@0
|
204 msize = sMap.topol.msize;
|
wolffd@0
|
205 mdim = length(msize);
|
wolffd@0
|
206 munits = prod(msize);
|
wolffd@0
|
207
|
wolffd@0
|
208 [dlen dim] = size(D);
|
wolffd@0
|
209 if dlen<2,
|
wolffd@0
|
210 %if dlen==1, sMap.codebook = (sMap.codebook - 0.5)*diag(D); end
|
wolffd@0
|
211 error(['Linear map initialization requires at least two NaN-free' ...
|
wolffd@0
|
212 ' samples.']);
|
wolffd@0
|
213 return;
|
wolffd@0
|
214 end
|
wolffd@0
|
215
|
wolffd@0
|
216 % compute principle components
|
wolffd@0
|
217 if dim > 1 & sum(msize > 1) > 1,
|
wolffd@0
|
218 % calculate mdim largest eigenvalues and their corresponding
|
wolffd@0
|
219 % eigenvectors
|
wolffd@0
|
220
|
wolffd@0
|
221 % autocorrelation matrix
|
wolffd@0
|
222 A = zeros(dim);
|
wolffd@0
|
223 me = zeros(1,dim);
|
wolffd@0
|
224 for i=1:dim,
|
wolffd@0
|
225 me(i) = mean(D(isfinite(D(:,i)),i));
|
wolffd@0
|
226 D(:,i) = D(:,i) - me(i);
|
wolffd@0
|
227 end
|
wolffd@0
|
228 for i=1:dim,
|
wolffd@0
|
229 for j=i:dim,
|
wolffd@0
|
230 c = D(:,i).*D(:,j); c = c(isfinite(c));
|
wolffd@0
|
231 A(i,j) = sum(c)/length(c); A(j,i) = A(i,j);
|
wolffd@0
|
232 end
|
wolffd@0
|
233 end
|
wolffd@0
|
234
|
wolffd@0
|
235 % take mdim first eigenvectors with the greatest eigenvalues
|
wolffd@0
|
236 [V,S] = eig(A);
|
wolffd@0
|
237 eigval = diag(S);
|
wolffd@0
|
238 [y,ind] = sort(eigval);
|
wolffd@0
|
239 eigval = eigval(flipud(ind));
|
wolffd@0
|
240 V = V(:,flipud(ind));
|
wolffd@0
|
241 V = V(:,1:mdim);
|
wolffd@0
|
242 eigval = eigval(1:mdim);
|
wolffd@0
|
243
|
wolffd@0
|
244 % normalize eigenvectors to unit length and multiply them by
|
wolffd@0
|
245 % corresponding (square-root-of-)eigenvalues
|
wolffd@0
|
246 for i=1:mdim, V(:,i) = (V(:,i) / norm(V(:,i))) * sqrt(eigval(i)); end
|
wolffd@0
|
247
|
wolffd@0
|
248 else
|
wolffd@0
|
249
|
wolffd@0
|
250 me = zeros(1,dim);
|
wolffd@0
|
251 V = zeros(1,dim);
|
wolffd@0
|
252 for i=1:dim,
|
wolffd@0
|
253 inds = find(~isnan(D(:,i)));
|
wolffd@0
|
254 me(i) = mean(D(inds,i),1);
|
wolffd@0
|
255 V(i) = std(D(inds,i),1);
|
wolffd@0
|
256 end
|
wolffd@0
|
257
|
wolffd@0
|
258 end
|
wolffd@0
|
259
|
wolffd@0
|
260 % initialize codebook vectors
|
wolffd@0
|
261 if dim>1,
|
wolffd@0
|
262 sMap.codebook = me(ones(munits,1),:);
|
wolffd@0
|
263 Coords = som_unit_coords(msize,'rect','sheet');
|
wolffd@0
|
264 cox = Coords(:,1); Coords(:,1) = Coords(:,2); Coords(:,2) = cox;
|
wolffd@0
|
265 for i=1:mdim,
|
wolffd@0
|
266 ma = max(Coords(:,i)); mi = min(Coords(:,i));
|
wolffd@0
|
267 if ma>mi, Coords(:,i) = (Coords(:,i)-mi)/(ma-mi); else Coords(:,i) = 0.5; end
|
wolffd@0
|
268 end
|
wolffd@0
|
269 Coords = (Coords-0.5)*2;
|
wolffd@0
|
270 for n = 1:munits,
|
wolffd@0
|
271 for d = 1:mdim,
|
wolffd@0
|
272 sMap.codebook(n,:) = sMap.codebook(n,:)+Coords(n,d)*V(:, d)';
|
wolffd@0
|
273 end
|
wolffd@0
|
274 end
|
wolffd@0
|
275 else
|
wolffd@0
|
276 sMap.codebook = [0:(munits-1)]'/(munits-1)*(max(D)-min(D))+min(D);
|
wolffd@0
|
277 end
|
wolffd@0
|
278
|
wolffd@0
|
279 % training struct
|
wolffd@0
|
280 sTrain = som_set(sTrain,'time',datestr(now,0));
|
wolffd@0
|
281 sMap.trainhist = sTrain;
|
wolffd@0
|
282
|
wolffd@0
|
283 return;
|
wolffd@0
|
284
|
wolffd@0
|
285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|