function [w,bias] = train(negative,positive)

% train.m
%
% Octave function to train a perceptron.
% (Code written for GNU Octave should also run in Matlab)
%
% Expects negative examples to be in negative.txt 
% and positive examples to be in positive.txt
%
% The binary feature vectors should be built with feature.pl
%
% Sparse matrix representation and operations are not used, although 
% they would be much more efficient. There was little point, because 
% sparse matrices are only implemented in Matlab (which costs about 
% US$2000 and is inaccessible to most IF developers).
%
% This program implements the same algorithm, and should do the same
% thing, as the Perl program "train.pl" that is included with Perform.
%
% Perform (Perceptron Classifier in Inform) v1.0
% Nick Montfort  http://nickm.com  2004-06-24


if (size(negative,2) != size(positive,2))
  printf("Dimensions of positive and negative examples don't match.\n");
  break;
end

printf("Data looks good. Beginning training...\n");
fflush(stdout);

d = size(negative,2);
w = zeros(1,d);
bias = 0;
% Initially, all the negative examples are correctly classified by
% a zero weight vector:
tneg = zeros(1,size(negative,1));
% But the zero weight vector misclassifies all the positive examples:
tpos = ones(1,size(positive,1));
i = 0;

while ((sum(tneg) + sum(tpos)) > 0)
  i++;
  printf("Starting iteration %i beginning with ", i);
  printf("%i (-) and %i (+) misclassified...\n", sum(tneg), sum(tpos));
  fflush(stdout);
  w = w - (tneg * negative) + (tpos * positive);
  bias = bias - sum(tneg) + sum(tpos);
  for j=(1:size(negative,1));
    tneg(j) = ((sum(negative(j,:) * w') + bias) > 0);
  end
  for j=(1:size(positive,1));
    tpos(j) = ((sum(positive(j,:) * w') + bias) <= 0);
  end
end

printf("Finished, with %i misclassified.\n", sum(tneg) + sum(tpos));