⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 [基础] 多功能计算函数evalf() _evalf.m

📁 熟悉matlab的人都会很清楚matlab中的feval()函数没法对匿名函数进行运算
💻 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 + -