www.gusucode.com > mbcdata 工具箱 matlab 源码程序 > mbcdata/@cgoppoint/check_eval.m
function [ok,all_need_ptrs,OpParents,order] = check_eval(p,things,parents,vectors) %CHECK_EVAL Pre-evaluation checking for dataset % % ok = check_eval(P) checks evaluation for each factor % ok = check_eval(P,ptrlist) % ok = check_eval(P,indexlist) % ok = check_eval(P,{expressions}) % [ok, need_ptrs] = check_eval(...) returns value pointers required % % check_eval(p,exprs,getptrs,vectors) passes in the getptrs for each of exprs % and the ptrs to all vectors required. This is faster, if these are known. % % [ok, need_ptrs, order] = check_eval(p) returns evaluation order for factors % [ok, need_ptrs, order] = check_eval(p,oldorder) starts with old order % % Use check_eval prior to calling i_eval. % % See also: i_eval, eval_fill % Copyright 2000-2008 The MathWorks, Inc. and Ford Global Technologies, Inc. order = []; OpParents = []; ok = []; all_need_ptrs = []; if nargout>2 && (nargin~=1 && nargin~=2) error(message('mbc:cgoppoint:InvalidArgument15')); elseif nargout>2 if nargin<2 things = 1:length(p.ptrlist); end order = 1:length(p.ptrlist); elseif nargin<2 things = 1:length(p.ptrlist); elseif nargin<1 error(message('mbc:cgoppoint:TooFewInputs4')); end if isnumeric(things) if ~all(ismember(things,1:length(p.ptrlist))) error(message('mbc:cgoppoint:InvalidIndex10')); end if ~isempty(order) order = [things setdiff(1:length(p.ptrlist),things)]; end if isempty(things) if ~isempty(p.ptrlist) && any(isvalid(p.ptrlist)) % things is left unaltered in the case of a data set purely consisting % of imported data. Nothing to evaluate. things = 1:length(p.ptrlist); end end elseif isa(things,'xregpointer') for i = 1:length(things) if ~isvalid(things(i)) || ~things(i).isa('cgexpr') error(message('mbc:cgoppoint:InvalidArgument16')); end end elseif iscell(things) for i = 1:length(things) if ~isa(things{i},'cgexpr') error(message('mbc:cgoppoint:InvalidArgument17')); end end elseif isa(things,'expression') things = {things}; else error(message('mbc:cgoppoint:InvalidArgument18')); end if nargin<3 parents = []; elseif length(parents)~=length(things) error(message('mbc:cgoppoint:InvalidArgument19')); end if nargin<4 vectors = []; end factors = get(p,'factors'); if isempty(p.factor_type) ig_i = []; else ig_i = find(p.factor_type==0); end AllOpPtrs = p.ptrlist; % Outputs: assigned outputs are taken as inputs. % non-assignable outputs must be evaluated overwrite = get(p,'iseditable'); use_i = find(overwrite); if ~isempty(order) % bring overwrites to front of order % also bring group members together (may be reshuffled later if necessary) order = [order(ismember(order,use_i)) order(~ismember(order,use_i))]; end % record which factors we've checked for evaluation % and found parents for. done_factor = zeros(1,length(factors)); % inputs and assigned outputs can be evaluated - set flag % (unless they are linked) done_factor(use_i) = 1; check = done_factor; % Going to check the parents of each expression, % and allow evaluation if the dataset includes all % vector inputs, or replaces all vector inputs. % Keep valid input (and assigned output) pointers. LinkPtrs = get(p,'linkptrlist'); if isempty(AllOpPtrs) use_i = []; OpPtrs = []; else valid = isvalid(AllOpPtrs); % ensure all ptrs are valid use_i = use_i(find(valid(use_i))); OpPtrs = AllOpPtrs(use_i); %only keep inputs and assigned outputs end if isempty(OpPtrs) % make sure OpPtrs is an xregpointer OpPtrs= null(xregpointer,[1,0]); end % Specials - eg feature; linkptr is actually the one we want to check against % (original ptr is used to generate correct icon) if ~isempty(p.ptrlist) sp = find(p.created_flag==-2); AllOpPtrs(sp) = p.linkptrlist(sp); end OpParents = cell(1,length(factors)); OpParents(use_i)= pveceval( OpPtrs,@getAllInputs); OpNeed = cell(1,length(factors)); for j = 1:length(things) evalptr = []; evalfactor = []; evalexpr = []; out = []; need_ptrs = []; if isnumeric(things) evalfactor = things(j); elseif isa(things,'xregpointer') if isempty(AllOpPtrs) evalptr = things(j); else f = find(things(j)==AllOpPtrs); if length(f)==1 evalfactor = f; else evalptr = things(j); end end elseif iscell(things) name = getname(things{j}); f = strcmp(name,factors); if length(f)==1 evalfactor = f; else evalexpr = things{j}; end else error(message('mbc:cgoppoint:InvalidState7')); end thisparents = []; if ~isempty(evalfactor) evalptr = []; if ~isvalid(AllOpPtrs(evalfactor)) % unassigned factor - can be evaluated providing data is present out = 1; elseif ~done_factor(evalfactor) [done_factor,check,OpParents,OpNeed,order] = ... i_DoFactor(evalfactor,OpPtrs,AllOpPtrs,LinkPtrs,done_factor,check,OpParents,OpNeed,order,ig_i,vectors); end out = check(evalfactor); need_ptrs = OpNeed{evalfactor}; end if ~isempty(parents) thisparents = parents{j}; else if ~isempty(evalptr) thisparents = getAllInputs(info(evalptr)); elseif ~isempty(evalexpr) thisparents = getAllInputs(evalexpr); end end if isempty(thisparents) && isempty(out) % values do not have parents. % Cannot evaluate a value if it is not in dataset. % Values which are in dataset are picked out as evalfactor. out = 0; % Return the needed pointer. This fails if trying to evaluate % an expression (eg a value) - no way round this one. need_ptrs = evalptr; % check for special case of subfeature with no model or equation if ~isempty(evalptr) && isvalid(evalptr) if evalptr.isa('cgfeature') out = 1; need_ptrs = []; end end end if isempty(out) % haven't yet decided if ok % So - an expression (but not a value) not in the dataset. [out,need_ptrs,done_factor,check,OpParents,OpNeed,order] = ... i_CheckPtr(thisparents,OpPtrs,AllOpPtrs,LinkPtrs,done_factor,check,OpParents,OpNeed,order,ig_i,vectors); end ok = [ok out]; all_need_ptrs = [all_need_ptrs {need_ptrs}]; end %------------------------------------------------------------------- function [done_factor,check,OpParents,OpNeed,order] = ... i_DoFactor(i,OpPtrs,AllOpPtrs,LinkPtrs,done_factor,check,OpParents,OpNeed,order,ig_i,vectors) %------------------------------------------------------------------- % get parents for this factor OpParents{i} = getAllInputs(AllOpPtrs(i).info); % Is this factor linked? Continue using the link and its parents. % For ignored factors, use parents as normal. if isvalid(LinkPtrs(i)) && ~ismember(i,ig_i) % pass link parents on to next routine. thisparents = [LinkPtrs(i) getAllInputs(LinkPtrs(i).info)]; else thisparents = OpParents{i}; end done_factor(i) = 1; % No parents -> a value (prob. set to ignore) % Cannot evaluate unless linked if isempty(OpParents{i}) && isempty(thisparents) check(i) = 0; else % check evaluation of this factor % This bit may go recursive if this factor depends on another. % Recursion ends when an input factor is found (done_factor and check % are already set for certain factors). [out, need, done_factor, check, OpParents, OpNeed, order,dep_factor] = ... i_CheckPtr(thisparents,OpPtrs,AllOpPtrs,LinkPtrs,done_factor,check,OpParents,OpNeed,order,ig_i,vectors); check(i) = out; OpNeed{i} = need; % working out evaluation order? % check dependent factors if ~isempty(order) % find current position of this factor f = find(i==order); if ~isempty(f) mx = f; % find highest position of a dependent factor for j = 1:length(dep_factor) mx = max(mx,find(dep_factor(j)==order)); end % place current factor after highest dependent order = order([1:f-1 f+1:mx f mx+1:end]); end end end %------------------------------------------------------------------- function [out,need_ptrs,done_factor,check,OpParents,OpNeed,order,dep_factor] = ... i_CheckPtr(thisparents,OpPtrs,AllOpPtrs,LinkPtrs,done_factor,check,OpParents,OpNeed,order,ig_i,vectors) %------------------------------------------------------------------- % dep_factor is only used in i_DoFactor, to work out evaluation order. % If the thing is a factor, we must get to this routine through i_DoFactor. rem_i = []; need_ptrs = []; dep_factor = []; % Check whether any factors are included in parents list. % Do evaluation check on factor, if not already done, % and if ok, remove parents of this factor from ptr list. % This section done with all factors (AllOpPtrs) which are part of % thisparents NeedChecking= ismember(AllOpPtrs,thisparents); for i = find(NeedChecking); % find all instances of AllOpPtrs(i) in thisparents f = findindex(AllOpPtrs ,thisparents,i); if ~isempty(f) %matched something dep_factor = [dep_factor i]; if ~done_factor(i) % work out if this factor can be evaluated [done_factor,check,OpParents,OpNeed,order] = ... i_DoFactor(i,OpPtrs,AllOpPtrs,LinkPtrs,done_factor,check,OpParents,OpNeed,order,ig_i,vectors); end if check(i) % only remove parents if we can evaluate the thing rem = OpParents{i}; %any parents to remove? inds = findptrs(rem, thisparents); rem_i = [rem_i, f, inds]; % for j = 1:length(f) %may have several instances % rem_i = [ rem_i [f(j):f(j)+length(rem)] ]; %relies on ptrs being returned the same by getptrs % end end end end thisparents(rem_i) = []; %get rid of parents % Check whether remaining parent list contains any vectors % which are not dataset inputs. % Compare against dataset inputs only (OpPtrs). if ~isempty(vectors) vecs_reqd = intersect(thisparents,vectors); need_ptrs = setdiff(vecs_reqd,OpPtrs); out = isempty(need_ptrs); else out = 1; thisparents= unique(thisparents); thispinfo= infoarray(thisparents); in = false(1,length(thisparents)); for i = 1:length(thisparents) in(i)= isinport( thispinfo{i} ); end need_ptrs= thisparents(in); out= ~any(in); end