// clustering folosind o retea neuronala uninivel cu antrenare nesupervizata
function [nn,etichete]=WTA(a,b,K)
//[x,n]=generare(a,b,K); // generare date (aleator)
[x,n]=selectiePcte(a,b); // generare date (selectie pcte - click dreapta mouse)
nn=tlist(["retea WTA", "X","W","Y"],zeros(2,1),zeros(K,2),zeros(K,1));
disp(nn.W,"nn=");
C=init(x,n,K); // selectie reprezentanti
nn.W=C';       // setare ponderi pentru unitatile de iesire
etichete=zeros(1,n);
disp(nn.W,"W=");
eta=0.1;
for t=1:100   // algoritm iterativ de invatare (Winner Takes All)
  for i=1:n   // parcurgere set de date
     imin=winner(nn,x(:,i));   // determinare unitate invingatoare   
     nn.W(imin,:)=nn.W(imin,:)+eta*(x(:,i)'-nn.W(imin,:));  // ajustare
  end
  eta=eta*0.995;   // ajustarea ratei de invatare
  disp(t,"t="); disp(eta,"eta=");
end

clf;
plot(x(1,:),x(2,:),'ko');   // vizualizarea punctelor
culori=['ro','go','bo','ko','yo','co'];
culori2=['r*','g*','b*','k*','y*','c*'];
// asignarea datelor la clase
for i=1:n do
   etichete(i)=winner(nn,x(:,i));
end   
// vizualizarea claselor identificare
for i=1:n do
    plot(x(1,i),x(2,i),culori(etichete(i)));
end

for k=1:K do
    plot(nn.W(k,1),nn.W(k,2));
end
endfunction

function imin=winner(nn,x)
    //for i=1:n
        for k=1:K
           d(k)=dist(x,nn.W(k,:)');
        end   
        imin=1;
        for k=2:K
            if d(k)<d(imin) 
                imin=k;
            end
        end     
     //end  
//     disp(imin,"imin=");
endfunction    

// cautarea unui element
function rez=prezent(ind,m,i)
rez=0;
for j=1:m
    if ind(j)==ind(i) 
        rez=1;
    end
end    
endfunction        

// initializarea prototipurilor prin selectie aleatoare din setul de date
function C=init(x,n,K)
ind=zeros(1,K);
for i=1:K
    ind(i)=grand(1,1,"uin",1,n);
    //se verifica daca prototipul a fost deja selectat 
    while prezent(ind,i-1,i)==1   
        ind(i)=grand(1,1,"uin",1,n);
    end
end    
for i=1:K
   C(:,i)=x(:,ind(i));
end   
disp(ind,"Indici selectati:");
disp(C,"C=");
endfunction

// calcul distanta euclidiana (patratul distantei)
function d=dist(x,y)
n=length(x);
d=0;
for i=1:n
    d=d+(x(i,1)-y(i,1))^2;
end    
endfunction

// generare de date bidimensionale aleator (utilizand o repartitie normala) 
// in [a,b]x[a,b]
function [x,n]=generare(a,b,K)
x=[]; n=0; sigma=(b-a)/(8*K);
for k=1:K
  nr=grand(1,1,"uin",5,50);
  n=n+nr;
  xc=grand(1,1,"unf",a,b);
  yc=grand(1,1,"unf",a,b);
  for i=1:nr
    x=[x [grand(1,1,"nor",xc,sigma);grand(1,1,"nor",yc,sigma)]];
  end
end
endfunction

function [x,n]=selectiePcte(a,b)
   // data input
   clf;
   plot2d(0,0,0,rect=[a,a,b,b]);
   xgrid(3);
   p=locate(-1,1);   
   n=size(p,2); 
   x = p;
endfunction  


WTA(0,1,4)
