function [x, y] = loadLabeledNumericalData(fname, nExpectedLines, ...
					   nExpectedCols, indLabel, codings)
% Loads a labeled data file (delimited ASCII); returns a 
% matrix of observations (as columns!) and a class coding matrix
% (as columns, taken from the given prototype codings).
%
% NOTES: 
%
%   - The file must have one observation on each line, variables 
%     separated by commas
%
%   - All data must be numerical (pre-process any string
%     categorization to integers!)
%
%   - The entry at index indLabel on each line is interpreted as the
%     class label (The parameter is required to ascertain that you know 
%     whether your label is the first, the last, or some other).
%
%   - The label will be removed from the output matrix x.
%
%   - The class codings must be given as column vectors.  If codings
%     are omitted, the integer number coding read from the file will
%     be used.
%
%   - You must know the expected number of lines and columns in the
%     file (this safeguards against dlmread strangenesses due to
%     extra spaces or something.. strange platform-dependent problems 
%     I've encountered and circumvented by these forced parameters. TODO:
%     would be nice to know what the real story is)
%
%   - Example of a valid file format:
%
%        1.3,1,0,0,768,0
%        1.2,0,1,0,768,1
%        1.8,1,1,-0.31,1e+8,0
%        1.2,0,1,0,769,2
%        ...
%

%% Check arguments
if (nargin~=4 && nargin~=5)
  error('Expected 5 parameters; see help text for descriptions');
end

useIntegers = false;
if (nargin==4)
  warning('riscpros_mutil:revertToDefaultParam', ...
      'Label coding not specified. Assuming integer coding.');
  useIntegers = true;
end

%% Read data
% Read and transpose (->attributes as rows, observations as columns)
x = dlmread(fname);
x = x(1:nExpectedLines,1:nExpectedCols); % TODO: check if necessary on win/unix.
x = x';

% Extract the class label, and remove it.
classes = x(indLabel,:);
x = [x(1:indLabel-1,:) ; x(indLabel+1:end,:)];

% Regardless of the file format, force Labels in 1..N not 0..N-1
if min(classes)==0, classes = 1 + classes; end;

%% Check that the file was well-populated with labels
nclasses = numel(unique(classes));
maxclass = max(classes);

if nclasses ~= maxclass
  error(['Valid labels? ' ...
         'Mismatching # of distinct labels and max label value ' ... 
         fname ]); 
end

if useIntegers, codings = 1:nclasses; end;

if nclasses ~= size(codings,2)
  error(['Valid labels? ' ...
         'Mismatching # of prototypes and distinct labels in data ' ... 
         fname ]); 
end

%% Finally, apply the given label codings:
y = codings(:,classes);
