function uTest_Cell2Vec(doSpeed)
% Automatic test: Cell2Vec
% This is a routine for automatic testing. It is not needed for processing and
% can be deleted or moved to a folder, where it does not bother.
%
% uTest_Cell2Vec(doSpeed)
% INPUT:
% doSpeed: Optional logical flag to trigger time consuming speed tests.
% Default: TRUE. If no speed test is defined, this is ignored.
% OUTPUT:
% On failure the test stops with an error.
%
% Tested: Matlab 6.5, 7.7, 7.8, WinXP
% Author: Jan Simon, Heidelberg, (C) 2009-2010 matlab.THISYEAR(a)nMINUSsimon.de
% $JRev: R0q V:016 Sum:8kh0Rrl98A7+ Date:01-Oct-2010 15:06:16 $
% $License: BSD (see Docs\BSD_License.txt) $
% $File: Tools\UnitTests_\uTest_Cell2Vec.m $
% History:
% Initialize: ==================================================================
ErrID = ['JSimon:', mfilename];
LF = char(10);
% Default for the input:
if nargin == 0
doSpeed = true;
end
% Times for testing:
if doSpeed
randDelay = 5; % [sec], time for random tests
SpeedTime = 1.0; % [sec], time for speed tests
else
randDelay = 0.5;
SpeedTime = 0.25;
end
TestTime = 0.2; % Get number of loops
% Hello:
whichFunc = which('Cell2Vec');
disp(['==== Test Cell2Vec: ', datestr(now, 0), LF, ...
'Version: ', whichFunc, LF]);
% Determine if the MEX or M-version is called:
[dummy1, dummy2, fileExt] = fileparts(whichFunc); %#ok<ASGLU>
useMex = strcmpi(strrep(fileExt, '.', ''), mexext);
% Start tests: -----------------------------------------------------------------
% Standard tests - empty input, cell without populated elements, small known
% answer test:
S = Cell2Vec({});
if isempty(S) && isa(S, 'double')
disp(' ok: empty cell');
else
error(ErrID, 'Failed for empty cell.');
end
S = Cell2Vec(cell(1, 1));
if isempty(S) && isa(S, 'double')
disp(' ok: {NULL}');
else
error(ErrID, 'Failed for {NULL}.');
end
S = Cell2Vec(cell(1, 2));
if isempty(S) && isa(S, 'double')
disp(' ok: {NULL, NULL}');
else
error(ErrID, 'Failed for {NULL, NULL}.');
end
S = Cell2Vec({''});
if isempty(S) && ischar(S)
disp(' ok: {''''}');
else
error(ErrID, 'Failed for {''''}.');
end
S = Cell2Vec({'', ''});
if isempty(S) && ischar(S)
disp(' ok: {'''', ''''}');
else
error(ErrID, 'Failed for {'''', ''''}.');
end
S = Cell2Vec({'S'});
if isequal(S, 'S')
disp(' ok: {''S''}');
else
error(ErrID, 'Failed for {''S''}.');
end
S = Cell2Vec({'S1', 'S2'});
if isequal(S, 'S1S2')
disp(' ok: {''S1'', ''S2''}');
else
error(ErrID, 'Failed for {''S1'', ''S2''}.');
end
S = Cell2Vec({'S'; 'T'; 'UV'});
if isequal(S, 'STUV')
disp(' ok: {''S''; ''T''; ''UV''}');
else
error(ErrID, 'Failed for {''S''; ''T''; ''UV''}.');
end
S = Cell2Vec({'AAA', 'BB', [], 'C'});
if isequal(S, 'AAABBC')
disp(' ok: {''AAA''; ''BB''; [], ''C''}');
else
error(ErrID, 'Failed for {''AAA''; ''BB''; [], ''C''}.');
end
x = rand(10);
y = rand(11);
S = Cell2Vec({x, y});
if isequal(S, transpose([x(:); y(:)]))
disp(' ok: {rand(10), rand(11)}');
else
error(ErrID, 'Failed for {rand(10), rand(11)}.');
end
x = single(x);
y = single(y);
S = Cell2Vec({x, y});
if isequal(S, transpose([x(:); y(:)]))
disp(' ok: {single(rand(10)), single(rand(11))}');
else
error(ErrID, 'Failed for {single(rand(10)), single(rand(11))}.');
end
S = Cell2Vec({true, false});
if isequal(S, [true, false])
disp(' ok: {TRUE, FALSE}');
else
error(ErrID, 'Failed for type LOGICAL.');
end
if sscanf(version, '%d', 1) >= 7.0
typeList = {'int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32', ...
'int64', 'uint64'};
else % No RESHAPE or TRANSPOSE for UINT64 in Matlab 6.5...
typeList = {'int8', 'uint8', 'int16', 'uint16', 'int32', 'uint32'};
end
for iType = 1:length(typeList)
aType = typeList{iType};
x = feval(aType, round(rand(3,5) * 127));
y = feval(aType, round(rand(3,5) * 127));
S = Cell2Vec({x, y});
if isequal(S, reshape([x(:); y(:)], 1, []))
disp([' ok: {', aType, ', ', aType, '}']);
else
error(ErrID, ['Failed for type ', upper(aType)]);
end
end
% Random tests: ----------------------------------------------------------------
fprintf('\n== Random tests (%g sec):\n', randDelay);
DataC = strread(sprintf('%d,', fix(1000 .^ rand(1, 100))), ...
'%s', 'delimiter', ',');
lenDataC = length(DataC);
iniTime = cputime;
nTest = 0;
while cputime - iniTime < randDelay
for N = 0:99
C = DataC(fix(rand(1, N) * lenDataC) + 1);
if ~isequal(horzcat(C{:}), Cell2Vec(C))
error(ErrID, 'Failed for random test.');
end
end
nTest = nTest + 100;
end
fprintf(' ok: %d random tests passed.\n', nTest);
% Invalid input: ---------------------------------------------------------------
fprintf('\n== Check rejection of bad input:\n');
tooLazy = false;
try
dummy = Cell2Vec([]);
tooLazy = true;
catch
disp([' ok: [] rejected: ', LF, ' ', strrep(lasterr, LF, '; ')]);
end
if tooLazy
error(ErrID, '[] not rejected.');
end
if useMex % Less checks of inputs in M-version:
try
dummy = Cell2Vec({1, 'a'}); %#ok<*NASGU>
tooLazy = true;
catch
disp([' ok: {1, ''a''} rejected: ', LF, ...
' ', strrep(lasterr, LF, '; ')]);
end
if tooLazy
error(ErrID, '{1, ''a''} not rejected.');
end
try
dummy = Cell2Vec({'1', 2});
tooLazy = true;
catch
disp([' ok: {''1'', 2} rejected: ', LF, ' ', ...
strrep(lasterr, LF, '; ')]);
end
if tooLazy
error(ErrID, '{''1'', 2} not rejected.');
end
try
dummy = Cell2Vec({'1'}, []);
tooLazy = true;
catch
disp([' ok: ({''1''}, []) rejected: ', LF, ' ', ...
strrep(lasterr, LF, '; ')]);
end
if tooLazy
error(ErrID, '({''1''}, []) not rejected.');
end
else
disp(' ?: Reduced input checks for M-version');
end
% Speed: -----------------------------------------------------------------------
if doSpeed
fprintf('\n== Speed test (test time: %g sec):\n', SpeedTime);
else
fprintf('\n== Speed test (test time: %g sec - may be inaccurate):\n', ...
SpeedTime);
end
drawnow; % Allow update of external events
% TypeList = {'int8', 'int16', 'single', 'double'};
TypeList = {'double'};
CellSize = {[1,5], [1,10], [1,100], [10,1000]};
DataSize = {[1,1], [1,10], [1,100], [1,1000]};
fprintf(' Cell size: ');
for i = 1:length(CellSize)
fprintf('%9s', sprintf('%dx%d', CellSize{i}));
end
fprintf('\n');
rejectLargeData = false;
for iType = 1:length(TypeList)
aType = TypeList{iType};
for iDataSize = 1:length(DataSize)
aDataSize = DataSize{iDataSize};
fprintf(' Data: [%d x %d] %s\n', aDataSize, aType);
fprintf(' CAT(2, C{:}) ');
for iCellSize = 1:length(CellSize)
aCellSize = CellSize{iCellSize};
if rejectLargeData && ...
prod(aDataSize) >= 10000 && prod(aCellSize) >= 10000
PrintLoop([]);
continue;
end
CStr = cell(aCellSize);
for iC = 1:prod(aCellSize)
CStr{iC} = feval(aType, rand(aDataSize) * 255);
end
% Get number of loops (the WHILE CPUTIME loop has more overhead):
iTime = cputime;
N = 0;
while cputime - iTime < TestTime
S = cat(2, CStr{:});
clear('S');
N = N + 1;
end
N = max(2, round(N / (cputime - iTime) * SpeedTime));
% The actual test:
tic;
for iN = 1:N
S = cat(2, CStr{:});
clear('S');
end
NPerSec = N / (toc + eps); % Loops per second
PrintLoop(NPerSec);
drawnow; % Allow update of external events
end
fprintf(' loops/sec\n');
% ********
fprintf(' [C{:}] (HORZCAT!) ');
for iCellSize = 1:length(CellSize)
aCellSize = CellSize{iCellSize};
if rejectLargeData && ...
prod(aDataSize) >= 10000 && prod(aCellSize) >= 10000
PrintLoop([]);
continue;
end
CStr = cell(aCellSize);
for iC = 1:prod(aCellSize)
CStr{iC} = feval(aType, rand(aDataSize) * 255);
end
% Get number of loops (the WHILE CPUTIME loop has more overhead):
iTime = cputime;
N = 0;
while cputime - iTime < TestTime
S = [CStr{:}];
clear('S');
N = N + 1;
end
N = max(2, round(N / (cputime - iTime) * SpeedTime));
% The actual test:
tic;
for iN = 1:N
S = [CStr{:}];
clear('S');
end
NPerSec = N / (toc + eps); % Loops per second
PrintLoop(NPerSec);
drawnow; % Allow update of external events
end
fprintf(' loops/sec\n');
% ********
fprintf(' CELL2MAT(C) ');
for iCellSize = 1:length(CellSize)
aCellSize = CellSize{iCellSize};
if rejectLargeData && ...
prod(aDataSize) >= 10000 && prod(aCellSize) >= 10000
PrintLoop([]);
continue;
end
CStr = cell(aCellSize);
for iC = 1:prod(aCellSize)
CStr{iC} = feval(aType, rand(aDataSize) * 255);
end
% Get number of loops (the WHILE CPUTIME loop has more overhead):
iTime = cputime;
N = 0;
while cputime - iTime < TestTime
S = cell2mat(CStr);
clear('S');
N = N + 1;
end
N = max(2, round(N / (cputime - iTime) * SpeedTime));
% The actual test:
tic;
for iN = 1:N
S = [CStr{:}];
clear('S');
end
NPerSec = N / (toc + eps); % Loops per second
PrintLoop(NPerSec);
drawnow; % Allow update of external events
end
fprintf(' loops/sec\n');
% *********
fprintf(' Cell2Vec(C) ');
for iCellSize = 1:length(CellSize)
aCellSize = CellSize{iCellSize};
if rejectLargeData && ...
prod(aDataSize) >= 10000 && prod(aCellSize) >= 10000
PrintLoop([]);
continue;
end
CStr = cell(aCellSize);
for iC = 1:prod(aCellSize)
CStr{iC} = feval(aType, rand(aDataSize) * 255);
end
% Get number of loops (the WHILE CPUTIME loop has more overhead):
iTime = cputime;
N = 0;
while cputime - iTime < TestTime
S = Cell2Vec(CStr);
clear('S');
N = N + 1;
end
N = max(2, round(N / (cputime - iTime) * SpeedTime));
% The actual test:
tic;
for iN = 1:N
S = Cell2Vec(CStr);
clear('S');
end
NPerSec = N / (toc + eps); % Loops per second
PrintLoop(NPerSec);
drawnow; % Allow update of external events
end
fprintf(' loops/sec\n');
end % for iDataSize
fprintf('\n');
end % for iType
disp('Cell2Vec seems to work fine');
return;
% ******************************************************************************
function PrintLoop(N)
if isempty(N)
fprintf(' slow');
elseif N > 10
fprintf(' %7.0f', N);
else
fprintf(' %7.1f', N);
end
return;