0001 function model = dsPropagateFunctions(model, varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 if ~nargin
0018 model = localfunctions;
0019 return
0020 end
0021
0022
0023 options = dsCheckOptions(varargin,{'auto_gen_test_data_flag',0,{0,1}},false);
0024 if options.auto_gen_test_data_flag
0025 varargs = varargin;
0026 varargs{find(strcmp(varargs, 'auto_gen_test_data_flag'))+1} = 0;
0027 varargs(end+1:end+2) = {'unit_test_flag',1};
0028 argin = [{model}, varargs];
0029 end
0030
0031
0032 model=dsCheckModel(model, varargin{:});
0033 if ~isstruct(model.functions)
0034
0035 return;
0036 end
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 keep_going=1;
0047 while keep_going
0048 keep_going=0;
0049 update_these=fieldnames(model.functions);
0050 expressions=struct2cell(model.functions);
0051
0052
0053 for i=1:length(expressions)
0054 functions=model.functions;
0055 [expressions{i},keep_going]=insert_functions(expressions{i},functions, varargin{:});
0056 model.functions.(update_these{i})=expressions{i};
0057 end
0058 end
0059
0060
0061 functions=model.functions;
0062
0063
0064 target_types={'monitors','ODEs','ICs'};
0065
0066 for type_index=1:length(target_types)
0067 type=target_types{type_index};
0068
0069 s=model.(type);
0070 if isstruct(s)
0071 update_these=fieldnames(s);
0072 expressions=struct2cell(s);
0073
0074
0075 for i=1:length(expressions)
0076 if isempty(expressions{i})
0077 continue;
0078 end
0079
0080
0081 expressions{i}=insert_functions(expressions{i},functions, varargin{:});
0082 end
0083
0084
0085 model.(type)=cell2struct(expressions,update_these,1);
0086 end
0087 end
0088
0089
0090 if ~isempty(model.conditionals)
0091 target_types={'condition','action','else'};
0092 for type_index=1:length(target_types)
0093 type=target_types{type_index};
0094 expressions={model.conditionals.(type)};
0095
0096
0097 for i=1:length(expressions)
0098 if isempty(expressions{i})
0099 continue;
0100 end
0101
0102
0103 expressions{i}=insert_functions(expressions{i},functions, varargin{:});
0104 end
0105 [model.conditionals(1:length(model.conditionals)).(type)]=deal(expressions{:});
0106 end
0107 end
0108
0109
0110 if options.auto_gen_test_data_flag
0111 argout = {model};
0112
0113 dsUnitSaveAutoGenTestData(argin, argout);
0114 end
0115
0116 end
0117
0118
0119 function [expression,functions_were_found] = insert_functions(expression,functions, varargin)
0120
0121
0122 options = dsCheckOptions(varargin,{'auto_gen_test_data_flag',0,{0,1}},false);
0123 if options.auto_gen_test_data_flag
0124 varargs = varargin;
0125 varargs{find(strcmp(varargs, 'auto_gen_test_data_flag'))+1} = 0;
0126 varargs(end+1:end+2) = {'unit_test_flag',1};
0127 argin = [{expression}, {functions}, varargs];
0128 end
0129
0130 functions_were_found=0;
0131
0132 words=unique(regexp(expression,'[a-zA-Z]+\w*','match'));
0133 found_functions=words(ismember(words,fieldnames(functions)));
0134 if ~isempty(found_functions)
0135 functions_were_found=1;
0136
0137 for ff=1:length(found_functions)
0138
0139 found_function=found_functions{ff};
0140
0141
0142 found_expression=functions.(found_function);
0143
0144
0145 orig_var_list=regexp(found_expression,'^@\(([^\)]+)\)','tokens','once');
0146 orig_vars=regexp(orig_var_list{1},',','split');
0147
0148
0149
0150
0151 index=regexp(expression,[found_function '\('],'once');
0152 substr=expression(index:end);
0153 lb=find(substr=='(');
0154 rb=find(substr==')');
0155 ix=ones(size(lb));
0156
0157 for i=1:length(rb)
0158 pos=find(lb<rb(i)&ix==1,1,'last');
0159 if pos==1
0160 R=rb(i);
0161 break;
0162 else
0163 ix(pos)=0;
0164 end
0165 end
0166
0167
0168 new_var_list{1}=regexprep(substr(lb(1)+1:R-1),'([\(\)\+\*\.\^])','\\$1');
0169
0170
0171 new_vars=regexp(new_var_list{1},',','split');
0172
0173
0174 found_expression=regexp(found_expression,'^@\([^\)]+\)(.+)','tokens','once');
0175 found_expression=found_expression{1};
0176
0177 if length(orig_vars)~=length(new_vars)
0178 error('failed to match variables for function %s',found_function);
0179 end
0180
0181
0182 if ~isequal(orig_vars,new_vars)
0183 for v=1:length(orig_vars)
0184 found_expression=dsStrrep(found_expression,orig_vars{v},['(' new_vars{v} ')'], '', '', varargin{:});
0185 end
0186 end
0187
0188
0189 oldstr=[found_function '\(' new_var_list{1} '\)'];
0190
0191
0192 newstr=sprintf('(%s)',found_expression);
0193
0194
0195 expression=dsStrrep(expression,oldstr,newstr,'(',')', varargin{:});
0196 end
0197 end
0198
0199
0200 if options.auto_gen_test_data_flag
0201 argout = {expression, functions_were_found};
0202
0203 dsUnitSaveAutoGenTestDataLocalFn(argin, argout);
0204 end
0205
0206 end