function trainingCode(typeDataArray, saveName)

%This code uses the feature vectors stored above to train the algorithm,
% and store the weights as variable 'b' in a trainingWeightsFilename

% This code is copyrighted by Stanford University.
% Author: Ashutosh Saxena, Justin Drieymeyer
% Code cannot be used for commercial purposes.
% Use of the code, if used with permission from authors, must acknowledge:
% Learning to Grasp Novel Objects using Vision,
% Ashutosh Saxena, Justin Driemeyer, Justin Kearns, Chioma Osondu, Andrew Y. Ng. In 10th International Symposium on Experimental Robotics, ISER, 2006.
% Robotic Grasping of Novel Obects,
% Ashutosh Saxena, Justing Driemeyer, Justin Kearns, Andrew Y. Ng, In Neural Information Processing Systems (NIPS), 2006.
% More details at: http://ai.stanford.edu/~asaxena/learninggrasp/
% Version 0.1:   Aug 2006.



perceptionParameters;

global syntheticDataDirectory scratchDataDirectory
global trainingWeightsFilenameBase
global fullFeatsToUse

if nargin < 1
  %typeDataArray = {'thickpencil', 'martini', 'mug', 'teaTwo', 'eraser', 'emptyDishwasher', 'cerealbowl'};%, 'twoMugs', 'twoTeacups'};
  typeDataArray = {'thickpencil', 'martini', 'mug', 'teaTwo', 'eraser', 'cerealbowl'};%, 'twoMugs', 'twoTeacups'};
  %typeDataArray = {'mug', 'teaTwo', 'emptyDishwasher', 'martini', 'cerealbowl'};
  %typeDataArray = {'mug', 'teaTwo', 'martini', 'cerealbowl'};
  %typeDataArray = {'emptyDishwasher'};
  %typeDataArray = {'background'};
end

trainingWeightsFilename = trainingWeightsFilenameBase;

testOnAll = 0;

weightRealData = 1000;

%fullFeatureVector = [ ];
%fullTargetVector = [ ];
fullTargetVectorTableEdge = [ ];

trainFeatureSet = [ ];
trainTargetSet = [ ];
testFeatureSet = [ ];
testTargetSet = [ ];

maxNumToUse = 500;

weightVector = [];

loadFlag = 1;

if loadFlag
disp('Loading all the feature matrices');
for type = 1:(length(typeDataArray));

  typeData = char(typeDataArray(type));
  if nargin < 2
    trainingWeightsFilename = [trainingWeightsFilename typeData];
  end
  %% Old stuff used for multiple inference
  %if ((size(typeDataArray, 2) == 1) & strcmp(typeData, 'emptyDishwasher'))
  %  trainingWeightsFilename = trainingWeightsFilename1;
  %elseif (size(typeDataArray, 2) == 5)
  %  trainingWeightsFilename = trainingWeightsFilename2;
  %elseif ((size(typeDataArray, 2) == 1) & strcmp(typeData, 'background'))
  %  trainingWeightsFilename = trainingWeightsFilename3;
  %elseif (size(typeDataArray, 2) == 4)
  %  trainingWeightsFilename = trainingWeightsFilename4;
  %end

  directoryName = [syntheticDataDirectory '/' typeData '/']
  nFiles = length(dir([directoryName typeData '*.png']));
  batchVector = 0:25:min(nFiles+25,maxNumToUse);
  for batch = 1: (length(batchVector)-1)
    %for batch=1:(length(batchVector)-1)
    load([scratchDataDirectory '/Features/'  typeData '_' num2str(batch) '.mat']);
    %% Pick which target values to use here and set the others to zero
    if false
      targetVector = (targetVector > 0);
    else
      value = -1;
      if strcmp(typeData, 'thickpencil') || strcmp(typeData, 'martini') || strcmp(typeData, 'eraser')
        targetVector = (targetVector == 255);
        if (max(targetVector) == 1)
          disp(['Good value for ' typeData]);
        end
      elseif strcmp(typeData, 'mug') || strcmp(typeData, 'teaTwo')
        targetVector = (targetVector == 186);
        if (max(targetVector) == 1)
          disp(['Good value for ' typeData]);
        end
      elseif strcmp(typeData, 'twoMugs') || strcmp(typeData, 'twoTeacups')
        targetVector = (targetVector == 127);
        if (max(targetVector) == 1)
          disp(['Good value for ' typeData]);
        end
      else % strcmp(typeData, 'cerealbowl') || strcmp(typeData, 'emptyDishwasher')
        targetVector = (targetVector > 0);
        if (max(targetVector) == 1)
          disp(['Good value for ' typeData]);
        end
      end
    end

    RelNumNegExamples = 1.1;
    idealNumElements = floor(RelNumNegExamples*sum(targetVector) + 2);
    if strcmp(typeData, 'emptyDishwasher') | strcmp(typeData, 'background')
      idealNumElements = length(targetVector);
    end
    negInd = find(targetVector == 0);
    posInd = find(targetVector);
    tmpRnd = cumsum(rand(idealNumElements,1));
    randInd = 1 + floor( (size(negInd, 1) - 1) * tmpRnd / tmpRnd(end) );
    randInd = randInd( find(filter([1 -1], 1, randInd) ~= 0) );
    indToKeep = [posInd; negInd(randInd)];
    featureVector = featureVector(indToKeep, :);
    targetVector = targetVector(indToKeep);
    trainIndices = find( mod((1:size(featureVector,1)),4) == 1);
    testIndices = find( mod((1:size(featureVector,1)),4) == 0);
    if (strcmp(typeData, 'emptyDishwasher') | strcmp(typeData, 'background') | testOnAll)
      if (testOnAll ~= 1)
        trainIndicies = ~testIndices;
      end
      testFeatureSet = [testFeatureSet; featureVector(testIndices,fullFeatsToUse)];
      testTargetSet = [testTargetSet; targetVector(testIndices,1)];
    end
    trainFeatureSet = [trainFeatureSet; featureVector(trainIndices,fullFeatsToUse)];
    trainTargetSet = [trainTargetSet; targetVector(trainIndices,1)];

    thisWeightVector = ones(size(trainIndices));
    if strcmp(typeData, 'emptyDishwasher') | strcmp(typeData, 'background') | strcmp(typeData, 'emptyDishwasherZoomed')
      thisWeightVector = weightRealData * thisWeightVector;
    end
    weightVector = [weightVector thisWeightVector];

    %fullFeatureVector = [fullFeatureVector; featureVector];
    %fullTargetVector = [fullTargetVector; targetVector];
    %fullTargetVectorTableEdge = [fullTargetVectorTableEdge; targetVectorTableEdge];
    clear featureVector;
    clear targetVector;
  end
end
%save('trainingMatrices.mat', 'trainFeatureSet', 'trainTargetSet');
%save('testMatrices.mat', 'testFeatureSet', 'testTargetSet');

else
	disp('Loading presaved matrices');
	load('testMatrices.mat');
	load('trainingMatrices.mat');
end

disp(['Training on ' num2str( length(trainTargetSet)) ' data points and ' num2str(size(trainFeatureSet,2))  ]);
threshold = 1.2*sum(trainTargetSet) / length(trainTargetSet)

b = glmfit(trainFeatureSet, trainTargetSet, 'binomial', 'weights', weightVector);
    
if (nargin >= 2)
  trainingWeightsFilename = [trainingWeightsFilename saveName];
end
trainingWeightsFilename = [trainingWeightsFilename '.mat'];

save(trainingWeightsFilename, 'b', 'fullFeatsToUse');

predictions = glmval(b, trainFeatureSet, 'logit');
labels = (predictions > threshold);

disp('Error on Training data:::::::');
giveErrorNumbers(trainTargetSet, labels);


predictions = glmval(b, testFeatureSet, 'logit');
labels = (predictions > threshold);

disp('Error on test set:::::::');
giveErrorNumbers(testTargetSet, labels);


%testIndices = find( mod((1:size(fullFeatureVector,1)),4) == 0);
%trainIndices = find( mod((1:size(fullFeatureVector,1)),4) == 1);

%disp(['Training on ' num2str( length(trainIndices)) ' data points and ' num2str(size(fullFeatureVector,2))  ]);
%threshold = 1.2*sum(fullTargetVector(trainIndices,1)) / length(fullTargetVector(trainIndices,1))

%b = glmfit( [fullFeatureVector(trainIndices,:)], ...
%            fullTargetVector(trainIndices,1), 'binomial');

%save(trainingWeightsFilename, 'b');

%predictions = glmval(b, [fullFeatureVector(trainIndices,:)], 'logit');
%Y = fullTargetVector(trainIndices,:);
%labels = (predictions > threshold);

%disp('Error on Training data:::::::');
%giveErrorNumbers(Y, labels);


%predictions = glmval(b, [fullFeatureVector(testIndices,:)], 'logit');
%Y = fullTargetVector(testIndices,:);
%labels = (predictions > threshold);

%disp('Error on test set:::::::');
%giveErrorNumbers(Y, labels);
