function [s, n, i] = processRecurseRowsNonNaNInf(data, dim_num, a_func)
% processRecurseRowsNonNaNInf - Recursively process from dim_num down to row dimension and call function after removing NaN and Infs.
%
% Usage:
% [s, n, i] = processRecurseRowsNonNaNInf(data, dim_num, a_func)
%
% Parameters:
% a_db: A tests_db object.
% dim_num: Work down dimension (see mean).
% a_func: A function name or handle to be passed to feval that
% takes the data as the first argument and dimension to work as second.
%
% Returns:
% s: Resulting data matrix, with selected dimension removed.
% n: Numbers of used values in each call of a_func.
% i: indices returned by a_func.
%
% Description:
% Does a recursive operation over other dimensions in order to remove
% NaN and Inf values. This takes more time than applying the function directly.
%
% Example:
% >> b = processRecurseRowsNonNaNInf(rand(5, 5, 5), 1, 'mean')
% will find the mean of rows in each page of the random 3D matrix.
%
% See also: processDimNonNaNInf, max, mean, feval, tests_db
%
% $Id$
%
% Author: Cengiz Gunay <cgunay@emory.edu>, 2008/05/27
% Copyright (c) 2007 Cengiz Gunay <cengique@users.sf.net>.
% This work is licensed under the Academic Free License ("AFL")
% v. 3.0. To view a copy of this license, please look at the COPYING
% file distributed with this software or visit
% http://opensource.org/licenses/afl-3.0.php.
if dim_num == 1
sdata = data(~isnan(data(:)) & ~isinf(data(:)));
n = size(sdata, 1);
if n == 0
% If a divide by zero error occured,
% give it NaN value instead of an empty matrix.
s = NaN;
else
[s,i] = feval(a_func, sdata, 1);
end
else
for num=1:size(data, dim_num)
% Otherwise recurse
[dims{1:(dim_num-1)}] = deal(':');
dims{dim_num} = num;
[s(dims{:}) n(dims{:}) i(dims{:})] = ...
processRecurseRowsNonNaNInf(data(dims{:}), dim_num - 1, a_func);
end
end