%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Simple perceptron with sigmoid gain function
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 clear; clf;
 nIn =156; nOut=26;
 wOut=1*(rand(nOut,nIn)-0.5);

% training vectors (Letters)
 load pattern1;
 letterVectors=reshape(pattern1', 12*13, 26);
 rDes=diag(ones(1,26));

% Updating and training network 
% with sigmoid activation function and delta rule
 for sweep=1:1000;
     for i=1:26
        rIn=letterVectors(:,i);
        rOut=1./(1+exp(-wOut*rIn));
        dOut=(rOut.*(1-rOut)).*(rDes(:,i)-rOut);
        wOut=wOut+0.1*(rIn*dOut')';
     end
 
     % test all pattern
     distE=0;
     dist2=0;
     for i=1:26
        rIn=letterVectors(:,i);
        rOut=1./(1+exp(-wOut*rIn));
        distE=distE+0.5* sum((rDes(:,i)-rOut).^2);
        [rRec,iRec]=max(rOut);
        dist2=dist2 + (i~=iRec);
     end
       error(sweep)=distE;
       error2(sweep)=dist2;
       disp([sweep,error(sweep),error2(sweep)])
 end

 plot(error)
 hold on; plot(error2)
 title('sigmoidal perceptron with competive output layer')
 xlabel('# training steps')
 ylabel('average error (mean square and number of wrong pattern)')
 
 count=0;
 for iNoise = 0:1:90;      % loop over noise level
     count=count+1;
     noise(count)=iNoise;
     for iTrial=1:10;           % loop over trails
        dist2(iTrial)=0;
        for iLetter=1:26                 % loop over letter set
            rIn=letterVectors(:,iLetter);
            noiseVec=ranBinVec(156,iNoise*156/100);
            rIn(noiseVec==1)=rIn(noiseVec==1)==0;
            rOut=1./(1+exp(-wOut*rIn));
            [rRec,iRec]=max(rOut);
            dist2(iTrial)= dist2(iTrial) + (iLetter~=iRec);
        end
     end
     meanDist2(count)=mean(dist2);
     stdDist2(count)=std(dist2);
 end

 figure;
 errorbar(noise,meanDist2,stdDist2)
 title('sigmoidal perceptron with competive output layer')
 axis([0 90 0 26]);
 xlabel('noise [%]')
 ylabel('average number of wrong pattern')