wine_data;
% The program implements the Algorithm 8 in the textbook (p. 236)
% Batch relaxation with Margin.
% Note: The algorithm may not stop even if the training examples are linearly
% separable; it will not stop if the samples are not linearly separable.
% In this case, we want to normalize the data so that the variance is the same
% for all features
% Written by Xiuwen Liu for CAP 5638, Florida State University

normalize_flag = 1;
if normalize_flag ~= 0,
   for ccol=2:size(wine_ins,2),
      minV=min(wine_ins(:,ccol));
      maxV=max(wine_ins(:,ccol));
      varCol=var(wine_ins(:,ccol));
      wine_ins(:,ccol) = (wine_ins(:,ccol)-minV)/sqrt(varCol);
   end
end

c1_ind=find(wine_ins(:,1)==1);
wine_ins_c1=wine_ins(c1_ind,2:end);
c2_ind=find(wine_ins(:,1)==2);
wine_ins_c2=wine_ins(c2_ind,2:end);
c3_ind=find(wine_ins(:,1)==3);
wine_ins_c3=wine_ins(c3_ind,2:end);

startInd=[1:(C+1)]*0;
startInd(1)=0;
startInd(2)=startInd(1)+size(wine_ins_c1,1);
startInd(3)=startInd(2)+size(wine_ins_c2,1);
startInd(4)=startInd(3)+size(wine_ins_c3,1);
%keyboard
class1=1;
class2=2;
imgMat=wine_ins(:,1:end);
imgMat(:,1)=imgMat(:,1)*0+1;
imgMatOrg=imgMat;
%we need to normalize the dat
imgMat((startInd(class2)+1):startInd(class2+1),:)=0-imgMat((startInd(class2)+1):startInd(class2+1),:);
a=imgMat(1,:)*0;
a=rand(size(a))/10;
eta=2.75;
b=0.001;
k=0;
theta=0.0000000;
classes=[class1 class2];
while 1,
   k=k+1;
   gradient=a*0;
   Y=[''];
   missed=0;
   astr=[sprintf('%8.6f ', a)];
   disp([sprintf('Current weight at iteration %d: %s', k, astr)]);
   for i = classes,
      for j=(startInd(i)+1):startInd(i+1),
         net = a*imgMat(j,:)';
         if net  <= b,
            gradient=gradient+((b-net)/(sum(imgMat(j,:).^2)))*imgMat(j,:);
            missed=missed+1;
            Y=[Y sprintf('%d(%d) ',j,i)];
         end
      end
   end
   if length(Y)<1,
      disp([sprintf('All classified correctly after %d iterations.',k)]);
      break;
   end
   disp([sprintf('%d samples are misclassified at iteration %d\n\t and they are %s', missed, k, Y)]);
   prev_a = a;
   a=a+(eta/missed)*gradient;
   if sum( (a-prev_a).^2) < theta*theta,
      fprintf(1,'The weight vector has almost converged and the change is only %18.10f.\n', ...
         sqrt(sum( (a-prev_a).^2)));
      break;
   end
end
pause
astr=[sprintf('%8.6f ', a)];
disp([sprintf('Current weight at iteration %d: %s', k, astr)]);
disp(['Now classifying the patterns using the learned weights:']);
for i = classes,
   for j=(startInd(i)+1):startInd(i+1),
      g=a*imgMatOrg(j,:)';
      if g > 0,
         classified=class1;
      else
         classified=class2;
      end
      if i==classified,
         outcomeStr=['correct'];
      else
         outcomeStr=['wrong'];
      end
      disp([sprintf('Sample %d (%d) g=%8.6f classified as %d, which is %s', j, i, g, classified, outcomeStr)]);
   end
end
