### Highlights fromNeural Networks: A Comprehensive Foundation, 2e book Companion Software

from Neural Networks: A Comprehensive Foundation, 2e book Companion Software by Simon Haykin
Companion Software for Neural Networks: A Comprehensive Foundation, 2e book

[W_out, p_out]=som_2d(P, nsofmx, nsofmy, epochs, phas, W)
```function [W_out, p_out]=som_2d(P, nsofmx, nsofmy, epochs, phas, W)

% function W=som_2d(P, nsofmx, nsofmy, epochs, phas, W)
%
% uses a Gaussian neighbourhood thus size refers to the spread of the Gaussian
%
%    P      - patterns
%    nsofmx/y  - number of neurons
%    epochs - number of epochs to train for
%    phas   - either
%             two element vector for ordering phase
%               [initial_learning_rate initial_neighbourhood_size]
%               these values will decrease exponentially during training
%             four element vector for convergence phase
%               [initial_learning_rate         final_learning_rate ...
%                initial_neighbourhood_size    final_neighbourhood_size]
%               these values will decrease linearly during training
%    W      - initial weight values (optional)
%
%    W_out  - final weights
%    p_out  - final values for learning rate and neighbourhood size
%
% Hugh Pasika   1997

r=nsofmx;  c=nsofmy; cr=r+1; cc=c+1;
[pats dimz]=size(P);
if nargin < 6, W=randn(nsofmx,nsofmy,dimz)*.1; end
mx=min(P(:,1));mxx=max(P(:,1));
my=min(P(:,2));myx=max(P(:,2));

n = 1:epochs;

if length(phas) == 2,
so = phas(2);
t1 = epochs/(log(so+1));
sigmas = so*exp(-n/t1);
lrs    = phas(1)*exp(-n/epochs);
else
sigmas = (phas(3)-phas(4))*fliplr(n)/epochs+phas(4);
lrs    = (phas(1)-phas(2))*fliplr(n)/epochs+phas(2);
end

x=[-c:c];   y=[r:-1:-r];
for i=1:length(x), for j=1:length(y),
end
end

sigma=sigmas(1)
m = m/max(max(m));
lbr =cr-floor(r/2);
ubr =cr+floor(r/2);
lbc =cc-floor(r/2);
ubc =cc+floor(r/2);

sigma=sigmas(length(sigmas));
m = m/max(max(m));

ax=(max(abs([max(P) min(P)]))); % outer boundary for graphing
ax=([min(P(:,1)) max(P(:,1)) min(P(:,2)) max(P(:,2)) ]);

for epoch=1:epochs,
t=clock;
[neword]=shuffle(P);
sigma=sigmas(epoch);
for pat=1:pats,

in=neword(pat,:)';
Dup=in(:,ones(r,1),ones(c,1));
Dup=permute(Dup,[2,3,1]);
Dif= W - Dup;
Sse=sum(Dif.^2,3);
[val1 win_rows]=min(Sse); [val2 wc]=min(val1); wr=win_rows(wc);
WN(pat,1:2)=[wr wc];

M1 = (1/(2*pi*sigma^2)*exp((-M1.^2/(2*sigma^2))));
M1 = M1/max(max(M1)); 				  % gaussianiffy

M1=M1(:,:,ones(1,dimz));
W = W + lrs(epoch)*(Dup-W).*M1;                     % multiply

end

secs=etime(clock,t);
fprintf(1,'On epoch %i of %i next update approx %g seconds from now.\n\n',epoch,epochs,secs)
t=clock;

p_out = [lrs(length(lrs)) sigma];
W_out = W;

%   som_pl_map(W,1,2); drawnow

end

```