📄 [基础] 多功能计算函数evalf() _evalf.m
字号:
function varargout = evalf(varargin)
%EVALF Evaluates specified function in specified directory if required.
%
% SYNTAX:
% evalf(MATFUN)
% evalf(MATFUN,ARGINLIST)
% evalf('-t' ,MATFUN,...)
% evalf('-DIRNAME',MATFUN,...)
% [ARGOUTLIST] = evalf(...);
%
% INPUT:
% MATFUN - Unique MATLAB function/script handle, anonymous handle,
% file name or full-name to be evaluated.
% ARGINLIST - Comma separated input argument(s) of the function.
% DEFAULT: (non inputs)
% '-t' - From '-there', specifies whether the Current Directory
% should be changed to the one specified on the full-name
% file while function evaluation. Other option (besides
% '-DIRNAME') is '-h', from '-here'.
% DEFAULT: '-h' (evaluates in the Current Directory)
% '-RUNDIR' - Evaluates the function with this specified directory as
% momentarily current. For example: '-C:\MATLAB'.
% DEFAULT: ['-' pwd] (or the specified on full-name)
%
% OUTPUT:
% ARGOUTLIST - Comma separated output argument(s) of the function.
% DEFAULT: (non output)
%
% DESCRIPTION:
% MATLAB evaluates functions and scripts located only on the Current
% Directory (see PWD) or its list of directories (see PATH). This
% function allows the user to run any MATLAB function located in any
% location (specified by its full-name).
%
% Besides, while evaluating the function the Current Directory may be
% changed to the one specified on the full-name, or the one by
% '-RUNDIR'.
%
% Another important difference from MATLAB's FEVAL function, is that
% this function works correctly with anonymous function handles. In
% fact, functions given by name (strings) are converted into a function
% handle.
%
% NOTE:
% * When any optional argument is empty, [], its default value is used.
% * '-t' and '-h' are used instead of '-there' and '-here'
%
% EXAMPLE:
% x = linspace(0,4*pi);
% y = sin(x);
% % 1) Function and inputs versatility:
% hold on
% % By function name:
% evalf('plot',x,y,'b*')
% % By handle function:
% evalf(@plot,x,y,'ro');
% % By anonymous handle function:
% evalf(@(x,y,l)plot(x,y,l),x,y,'g');
% hold off
% legend('''plot''','@plot','@(x,y,l)plot(x,y,l)')
% % 2) Multiple outputs versatility:
% [vmax,imax] = evalf('max',[10 20 30 40 30 20 10])
% % 3) Directories versatility:
% % i) Evaluates LS on Current Directory directory:
% disp('i)')
% evalf ls
% % ii) Evaluates LS on previous directory:
% disp('ii)')
% evalf -.. ls
% % iii) Evaluates in its directory:
% disp('ii)')
% evalf('-t',[matlabroot '\toolbox\matlab\general\ls'])
%
% SEE ALSO:
% FEVAL, RUN, PATH, PWD.
%
%
% ---
% AUTHOR: Carlos Adrian Vargas Aguilera (MEXICO)
% CONTACT: nubeobscura@hotmail.com
% VERSION: 1.0 (Nov 10, 2008) (<a href="matlab:web('http://www.mathworks.com/matlabcentral/fileexchange/authors/11258')">download</a>)
% MATLAB: 7.5.0.342 (R2007b)
% ADDITIONAL NOTES:
% * In order to make the function compatible with previous MATLAB
% releases (although I couldn't test this), I avoided the use of some
% functions like FILESEP, RETHROW, STRCMPI, SWITCH-CASE short-circuit
% logicals, etc. I don't know if the TRY-CATCH is new, anyway I try
% to avoid it too. If there is some problem just let me know to make
% the appropiate changes. With VARARGIN, VARARGOUT, NARGIN and
% NARGOUT I cannot do too much. By the way, I don't know if ERROR and
% EXIST allow 2 inputs in previous releases.
% REVISIONS:
% 1.0 Released (Nov 10, 2008)
% Copyright 2008 Carlos Adrian Vargas Aguilera
% INPUTS CHECK-IN
% -------------------------------------------------------------------------
% Sets defaults:
dothere = false;
RUNDIR = [];
% Sets parameters:
oldcd = cd; % Current Directory.
sep = findstr(oldcd,'\'); % NOTE: I avoided the use of FILESEP.
if ~isempty(sep)
sep = '\'; % Windows
else
sep = '/'; % Linux
end
if ~strcmp(oldcd(end),sep), oldcd = [oldcd sep]; end
% Checks number of inputs:
if (nargin<1)
error('CVARGAS:evalf:notEnoughInputs', ...
'No function was specified.')
end
% Checks number of outputs:
if (nargout~=0)
varargout = cell(nargout,1);
end
% Checks '-t' or '-h' or '-RUNDIR' input:
if ischar(varargin{1})
if isempty(varargin{1})
error('CVARGAS:evalf:incorrectFirstInput',...
'First input cannot be empty.')
elseif strcmp(lower(varargin{1}(1)),'-')
% NOTE: I avoided the use of SWITCH-CASE.
if length(varargin{1})==1
error('CVARGAS:evalf:incorrectOptionalInput',...
'Optional first input must be ''-t'', ''-h'' or a valid ''-RUNDIR''.')
elseif strcmp(lower(varargin{1}(2)),'t')
% '-there':
dothere = true;
varargin(1) = [];
elseif strcmp(lower(varargin{1}(2)),'h')
% '-here':
varargin(1) = [];
else
% '-RUNDIR':
% NOTE: I avoided the use of short-circuit logical: ||.
RUNDIR = varargin{1}(2:end);
if ~strcmp(RUNDIR(end),sep), RUNDIR = [RUNDIR sep]; end
if strcmp(lower(RUNDIR),lower(oldcd))
RUNDIR = [];
elseif strcmp(RUNDIR,['.' sep])
RUNDIR = [];
elseif ~(exist(RUNDIR,'dir')==7)
error('CVARGAS:evalf:incorrectOptionalInput',...
'Optional first input must be ''-t'', ''-h'' or a valid ''-RUNDIR''.')
else
dothere = true;
end
varargin(1) = [];
end
end
% Checks if any input was left:
if isempty(varargin)
error('CVARGAS:evalf:notEnoughInputs',...
'No function was specified.')
end
end
% Checks MATFUN input:
MATFUN = varargin{1};
varargin(1) = [];
if isempty(MATFUN)
error('CVARGAS:evalf:notEnoughInputs',...
'No function was specified.')
elseif ischar(MATFUN)
% Function name.
% Looks if the function exist on its specified direction or, if not
% specified, in the Current Directory or PATH:
% NOTE: I avoided the use of ISMEMBER.
if ~(exist(MATFUN,'file')==2)
if ~(exist(MATFUN,'builtin')==5)
% Fixes DIR with '\' or '%' chars:
ind1 = findstr(MATFUN,'\');
if ~isempty(ind1)
N = length(MATFUN);
ind2 = zeros(1,N);
ind2(ind1) = 1;
MATFUN2( ind1+cumsum(ind2(ind1))-1) = '\';
MATFUN2((1:N)+cumsum(ind2)) = MATFUN;
MATFUN = MATFUN2;
end
ind1 = findstr(MATFUN,'%');
if ~isempty(ind1)
N = length(MATFUN);
ind2 = zeros(1,N);
ind2(ind1) = 1;
MATFUN2( ind1+cumsum(ind2(ind1))-1) = '%';
MATFUN2((1:N)+cumsum(ind2)) = MATFUN;
MATFUN = MATFUN2;
end
error('CVARGAS:evalf:incorrectMatfunInput', ...
['The function ''' MATFUN ''' was not found.'])
end
end
% Gets MDIR, MNAME and MEXT manually:
% NOTE: I avoided the use of FILEPARTS.
inddir = findstr(MATFUN,sep);
if isempty(inddir)
inddir = 0;
MDIR = [];
else
inddir = inddir(end);
MDIR = MATFUN(1:inddir);
end
indext = findstr(MATFUN(inddir+1:end),'.');
if isempty(indext)
indext = length(MATFUN)+1;
MEXT = [];
else
indext = indext(end);
MEXT = MATFUN(indext:end);
end
MNAME = MATFUN(inddir+1:indext-1);
% Checks MEXT:
if ~isempty(MEXT)
MEXT = lower(MEXT);
% NOTE: I avoided the use of SWITCH-CASE.
if strcmp(MEXT,'.m')
% continue
elseif strcmp(MEXT,'.p')
% continue
else
error('CVARGAS:evalf:incorrectFileExtension',...
'Function must be an M-file or ''.p''.')
end
end
% CHECKS MDIR:
% NOTE: I avoided the use of STRCMPI and short-circuit logical: ||.
gotoFDIR = ~isempty(MDIR) & ...
(~strcmp(lower(MDIR),lower(oldcd)) | ~strcmp(MDIR,['.' sep]));
if gotoFDIR
cd(MDIR)
else
MDIR = [];
if isempty(RUNDIR)
dothere = false;
end
end
% Gets the function handle:
if (exist('str2func','builtin')==5)
MATFUN = str2func(MNAME);
else
MATFUN = feval(['@' MNAME]);
end
elseif isa(MATFUN,'function_handle')
% Function handle.
% Just get the function name and dir:
MDIR = [];
if exist('func2str','builtin')==5
MNAME = func2str(MATFUN);
else
MNAME = [];
end
% Checks RUNDIR:
if isempty(RUNDIR)
dothere = false; % forces Current Directory
end
else
error('CVARGAS:evalf:incorrectMatfunInput',...
'MATFUN must be a function name or handle or anonymous handle.')
end
% -------------------------------------------------------------------------
% MAIN
% -------------------------------------------------------------------------
% Go to evaluation directory:
if ~dothere
% Evaluates on Current Directory:
if ~isempty(MDIR)
cd(oldcd)
end
oldcd = [];
elseif ~isempty(RUNDIR)
% Evaluates on RUNDIR:
cd(RUNDIR)
else
% Evaluates on MDIR (if full-name) or Current Directory.
end
% Evaluation:
if (exist('try','builtin')==5)
% Tries to evaluate in given directory, catching any error during
% evaluation to be able to return to previous Current Directory:
try
if nargout==0
MATFUN(varargin{:})
else
[varargout{:}] = MATFUN(varargin{:});
end
catch
if ~isempty(oldcd)
cd(oldcd)
end
if (exist('lasterror','builtin')==5)
message = lasterror;
message = message.message;
else
message = theerror;
end
error('CVARGAS:evalf:errorWhileEvauating',...
['Error during ' MNAME ' function evaluation. \n\n' message])
end
else
if nargout==0
MATFUN(varargin{:})
else
[varargout{:}] = MATFUN(varargin{:});
end
end
% Returns to previous directory:
if ~isempty(oldcd)
cd(oldcd)
end
% [EOF]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -