function res = map(fun, vec, type)
% map(fun, vec, [type]) - map a function to a vector or cell array
% fun -- a function handle, inline, or m-file name.  Must be a function
%  of only one argument
% vec --- a vector or cell array of items to be operated on
% type --- [] or {} : the desired type of the returned collection (either vector
%  or cell array) Default: vector if fun returns a number.
typeflag = (nargin >= 3);
   

% figure out what kind of thing <fun> returns
if iscell(vec) 
    foo = feval(fun,vec{1});
elseif isnumeric(vec)
    foo = feval(fun,vec(1));
else
    error('Map, vec must be vector or cell array.');
end
if typeflag
    outtype = {};
    if isnumeric(type) & isnumeric(foo)
        outtype = [];
    elseif isnumeric(type)
        warning('Vector requested: cell array required for output.');
    end
else
    if isnumeric(foo)
        outtype = [];
    else
        outtype = {};
    end
end
      
if iscell(vec)
    if isnumeric(outtype)
        % create a vector
        res = zeros(size(vec));
        res(1) = foo;
        for k=2:prod(size(vec))
            res(k) = feval(fun,vec{k});
        end
    else
        % it's not numeric, so return a cell array
        res = cell(size(vec));
        res{1} = foo;
        for k=2:prod(size(vec))
            res{k} = feval(fun, vec{k});
        end
    end
elseif isnumeric(vec)
    if isnumeric(outtype)
        % create a vector
        res = zeros(size(vec));
        res(1) = foo;
        for k=2:prod(size(vec))
            res(k) = feval(fun,vec(k));
        end
    else
        % it's not numeric, so return a cell array
        res = cell(size(vec));
        res{1} = foo;
        for k=2:prod(size(vec))
            res{k} = feval(fun, vec(k));
        end
    end  
else
    error('2nd arg. must be a vector or a cell array');
end
