function [net, vectors, labels] = demo_jedit(netCont)
% Trying the codes on the jEdit data from PROMISE data.
% This is quite similar to the iris example, but this is now the real
% hard-core stuff -- bug mining. I haven't used the data set before, and 
% I haven't studied the respective papers. This is here just to demonstrate
% how one might use the MLP approach for software metric data.
%
% During the little time that I spent with this, I could get no
% satisfactory results. So deal with this as an example, not a real
% application.. MLP doesn't look like a very promising method at least
% for unprocessed software metric data. But you can try.

% For training we need input vectors and corresponding target vectors.
DATADIR = 'data/';
[vectors,labels] = loadLabeledData([DATADIR ...
		    'jedit_data_numerical.dat'],369,8+1); 

rand('state', 123);
p = randperm(size(vectors,2));
vectors = vectors(:,p);
labels = labels(:,p);

% Let's cheat: scale all our data the same way. In reality we must NOT do 
% this, because the test data should be exactly that: not available during
% training. But this way the lecture demonstration showed a motivatingly 
% big accuracy :).
[vectors, traA, traB] = datatool_scale(vectors);

nt = floor(.8*size(vectors,2));
input   = vectors(:,1:nt);
target  =  labels(:,1:nt);
testx   = vectors(:,nt+1:end);
trueOut =  labels(:,nt+1:end);

% This would be a more proper place to make the scaling:
% Scale to [-1,1]:
%[input, traA, traB] = datatool_scale(input);
%testx = datatool_scale(testx,traA,traB);

% Pick random initial weights, and optimize from there:
rand('state', 1257);               % I'll pick a new seed here..
net = simple_mlp_create([size(input,1) 7 4 size(target,1)]);
net.regc=.003;

if nargin==1, net = netCont; end;  % unless we continue from
                                   % a previous end result

uFunc = @simple_mlp_evalMSErVecWrap;

% Here it takes quite many iterations to get any results; and they are still
% very bad, like <70%.
% At first sight, this looks like a very tough case, compared to the iris..
% Would need additional tricks for pre-processing or conditioning the MLP, 
% or then it would be better to use some other classification method
% altogether. Welcome to the world of data mining; you are the miner.
atOnce = 200;
outers = 10;
for s = 1:outers

  uPar.net = net;
  uPar.inputs = input;
  uPar.targets = target;

  x = simple_mlp_cell2vec(net.W);
  x = simple_mlp_optimCGP(x, uFunc, uPar, 1, atOnce, 0, 1e-6);
%  x = simple_mlp_optimGDh(x, uFunc, uPar, 0.1, atOnce, 0, 1e-6);
  net.W = simple_mlp_vec2cell(x, net.nneur);

  f = simple_mlp_evalMSEr(net, input, target);

  trainOut = simple_mlp_evalMSEr(net, input, 'feed');
  trainOut = class_compete(trainOut);
  trainRate = classif_rate(trainOut, target);
  
  testOut = simple_mlp_evalMSEr(net, testx, 'feed');
  testOut = class_compete(testOut);
  rate = classif_rate(testOut, trueOut);
  
  commentary = sprintf('Iter %d/%d: Cost=%f, TrainRate=%.3f TestRate=%.3f', ...
		       s*atOnce, outers*atOnce, f, trainRate, rate);
  disp(commentary);
  
  pause(0.1);
end


%% Helper function for loading a labeled data file (delimited ASCII).
function [x, y] = loadLabeledData(fname, nExpectedLines, nExpectedCols)
    % The column count seems necessary for some files..
    % Read and transpose (->attributes as rows, observations as columns)
    x = dlmread(fname);
    x = x(1:nExpectedLines,1:nExpectedCols); % TODO: check if
                                             % really necessary on win/unix.
    x = x';

    % Last attribute is expected to be a class name;
    % remove it from x and produce y as binary vector:
    classes = x(size(x,1),:);
    x = x(1:size(x,1)-1,:);

    if min(classes)==0, classes = 1+classes; end; % Labels in 1..N not 0..N-1
    nclasses = max(classes);

    y = -1 * ones(nclasses, size(x,2));
    for ind = 1:nclasses
      y(ind,classes == ind) = 1;
    end
    
    if max(y) ~= ones(1,size(y,2)); error('Valid data labels?'); end
      
    % A retrofitted hack.. If there are only two classes, we make it
    % binary with only one dimension! Three or more, we leave the
    % usual binary coding in effect.
    
    if nclasses==2
      t = y(2,:)==1;
      y = -1 * ones(1, size(x,2));
      y(t)=1;
    end
