www.gusucode.com > mbc 工具箱 matlab 源码程序 > mbc/@mbcinline/mbcinline.m
classdef (Hidden,Sealed) mbcinline % MBCINLINE replacement version of inline using anonymous functions % mbcinline expressions are vectorized unless explicitly devectorized % using the devectorize method % Copyright 2011-2015 The MathWorks, Inc. properties(SetAccess=private) %INPUTS list of inputs Inputs = {}; %EXPRESSION expression to evaluate Expression end properties (Access=private) %FHANDLE anonymous function handle for evaluation expression fHandle %VERSION object version Version = 2; end methods function obj=mbcinline(varargin) %MBCINLINE Construct MBCINLINE object. % MBCINLINE(EXPR) constructs an mbcinline function object from the % MATLAB expression contained in the string EXPR. The input % arguments are automatically determined by searching EXPR % for variable names (see SYMVAR). % % MBCINLINE(EXPR, ARG1, ARG2, ...) constructs an mbcinline % function whose input arguments are specified by the % strings ARG1, ARG2, ... Multicharacter symbol names may % be used. % % Examples: % g = mbcinline('t^2') % g = mbcinline('sin(2*pi*f + theta)') % g = mbcinline('sin(2*pi*f + theta)', 'f', 'theta') % g = mbcinline('x^P1', 1) % % See also SYMVAR. if nargin==1 if isa(varargin{1},'mbcinline') obj = varargin{1}; return else if isa(varargin{1},'sym') obj.Expression= char(varargin{1}); else obj.Expression= varargin{1}; end obj.Inputs = symvar(obj.Expression); if ~iscell(obj.Inputs) obj.Inputs = {obj.Inputs}; end end elseif nargin>1 obj.Expression= varargin{1}; if nargin==2 && iscell(varargin{2}) obj.Inputs = varargin{2}; else obj.Inputs = varargin(2:end); end % make sure Inputs is a column vector obj.Inputs=obj.Inputs(:); end % vectorize expression obj.Expression = vectorize(obj.Expression); % make anonymous function representation obj = makeAnon(obj); end function a = argnames(obj) %ARGNAMES Argument names. % ARGNAMES(FUN) returns the names of the input arguments of the % MBCINLINE object FUN as a cell array of strings. a = obj.Inputs; end function e=char(obj) %CHAR Convert MBCINLINE object to character array. % CHAR(FUN) returns the formula for the INLINE object FUN. % This is the same as FORMULA(FUN). % % See also MBCINLINE, MBCINLINE/FORMULA. e= obj.Expression; end function e=formula(obj) %FORMULA Function formula. % FORMULA(FUN) returns the formula for the INLINE object FUN. % % See also MBCINLINE/ARGNAMES, MBCINLINE/CHAR. e= obj.Expression; end function e=exist(obj) %#ok<*MANU> %EXIST for INLINE objects % EXIST(F) returns 1 when F is an MBCINLINE object. e= 1; end function obj = vectorize(obj) %VECTORIZE vectorize expression % replace *, /, \, ^ with .*, ./ , .\, .^ obj=mbcinline( vectorize(obj.Expression),obj.Inputs); end function s= sym(obj) obj = devectorize(obj); s = evalin(symengine, obj.Expression); end function obj = devectorize(obj) %DEVECTORIZE undoes vectorize % % gstr = devectorize(gstr) % SYM doesn't support .^,.*,./ operators gstr = obj.Expression; gstr= strrep(gstr,'.^','^'); gstr= strrep(gstr,'.*','*'); gstr= strrep(gstr,'./','/'); gstr= strrep(gstr,'.\','\'); % the constructor is not called as it vectorizes any expression obj.Expression = gstr; obj = makeAnon(obj); end end methods(Access=private) function obj = makeAnon(obj) %makeAnon make internal anonymous function from expression and %inputs if ~isempty(obj.Expression) try obj.fHandle = str2func( sprintf('@(%s) %s',mbcListString(obj.Inputs),obj.Expression) ); catch %#ok<CTCH> % undefined expression % MBC makes checks elsewhere to ensure that the expression % is evaluating correctly obj.fHandle=[]; end else obj.fHandle = []; end end end methods(Hidden) function varargout = subsref(obj,S) if length(S)==1 && strcmp(S.type,'()') [varargout{1:nargout}]=feval(obj,S.subs{:}); else [varargout{1:nargout}]=builtin('subsref',obj,S); end end function varargout = feval(obj,varargin) %FEVAL FEVAL an INLINE object. % We only want to call the @inline/feval if the first argument is % actually an inline. Otherwise, defer to the builtin feval. if ~isa(obj, 'mbcinline') % If any of the elements in varargin are inline objects, then the % overloaded inline feval is called even if the first argument % is not an inline (such as a string or a function handle). % In this case, we call the builtin feval. % varargout is needed here, although inline's only have one output, % since it could have been called with any number of outputs. [varargout{1:nargout}] = builtin('feval',obj,varargin{:}); else Ninputs = length(obj.Inputs); narginchk( Ninputs+1, Ninputs+1 ); if (isempty(obj.fHandle)) y = []; else % Need to evaluate expression in a function outside the @inline directory % so that f(x), where f is an inline in the expression, will call the % overloaded subsref. y = obj.fHandle(varargin{:}); end varargout{1} = y; end end function varargout = subsasgn(obj,S,New) error(message('mbc:mbcinline:subsasgn:notAllowed')); end function e=horzcat(varargin) error(message('mbc:mbcinline:horzcat:notAllowed')); end function e=vertcat(varargin) error(message('mbc:mbcinline:horzcat:notAllowed')); end function e=cat(varargin) error(message('mbc:mbcinline:horzcat:notAllowed')); end function n = nargout(obj) n = 1; end function n=nargin(obj) n = length(obj.Inputs); end end methods (Static) function obj = loadobj(obj) if isstruct(obj) && isfield(obj,'inline') % load from old oops version which extended inline obj = mbcinline.convertFromInline(obj.inline); end end function obj = convertFromInline(obj) %convertFromInline convert inline object to mbcinline if isa(obj,'inline') obj = mbcinline(formula(obj),argnames(obj)); elseif isstruct(obj) obj = mbcinline(obj.expr,obj.args); elseif ~isempty(obj) error(message('mbc:mbcinline:InvalidConversion', class( obj ))) else % obj is empty and returned from convertFromInline end end end end