Home > functions > internal > dsPropagateParameters.m

dsPropagateParameters

PURPOSE ^

PROPAGATEPARAMETERS - substitute parameter values or prepend parameter names with prefix across all model equations.

SYNOPSIS ^

function model = dsPropagateParameters(model,varargin)

DESCRIPTION ^

PROPAGATEPARAMETERS - substitute parameter values or prepend parameter names with prefix across all model equations.

 Usage:
   model = SubstituteParameters(model)

 Input:
   - model: DynaSim model structure
   - options:
     'action': {'substitute','prepend','postpend'} (default: substitute)
     'prop_prefix': string prepended to all parameter names if action is 'prepend'
     'prop_suffix': string postpended to all parameter names if action is 'postpend'

 Output: DynaSim model structure with updated parameter in all equations

 See also: dsPropagateFunctions, dsWriteDynaSimSolver

 Author: Jason Sherfey, PhD <jssherfey@gmail.com>
 Copyright (C) 2016 Jason Sherfey, Boston University, USA

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function model = dsPropagateParameters(model,varargin)
0002 %PROPAGATEPARAMETERS - substitute parameter values or prepend parameter names with prefix across all model equations.
0003 %
0004 % Usage:
0005 %   model = SubstituteParameters(model)
0006 %
0007 % Input:
0008 %   - model: DynaSim model structure
0009 %   - options:
0010 %     'action': {'substitute','prepend','postpend'} (default: substitute)
0011 %     'prop_prefix': string prepended to all parameter names if action is 'prepend'
0012 %     'prop_suffix': string postpended to all parameter names if action is 'postpend'
0013 %
0014 % Output: DynaSim model structure with updated parameter in all equations
0015 %
0016 % See also: dsPropagateFunctions, dsWriteDynaSimSolver
0017 %
0018 % Author: Jason Sherfey, PhD <jssherfey@gmail.com>
0019 % Copyright (C) 2016 Jason Sherfey, Boston University, USA
0020 
0021 %% localfn output
0022 if ~nargin
0023   model = localfunctions; % output var name specific to this fn
0024   return
0025 end
0026 
0027 % Check inputs
0028 model=dsCheckModel(model, varargin{:});
0029 if ~isstruct(model.parameters)
0030   % nothing to do
0031   return;
0032 end
0033 
0034 % Check inputs
0035 options=dsCheckOptions(varargin,{...
0036   'action','substitute',{'substitute','prepend','postpend'},...
0037   'prop_prefix','pset.p.',[],...
0038   'prop_suffix','',[],...
0039   'param_type','parameters',{'parameters', 'fixed_variables'},...
0040   'auto_gen_test_data_flag',0,{0,1},...
0041   },false);
0042 
0043 %% auto_gen_test_data_flag argin
0044 if options.auto_gen_test_data_flag
0045   varargs = varargin;
0046   varargs{find(strcmp(varargs, 'auto_gen_test_data_flag'))+1} = 0;
0047   varargs(end+1:end+2) = {'unit_test_flag',1};
0048   argin = [{model}, varargs]; % specific to this function
0049 end
0050 
0051 %% Finding parameters.
0052 parameters=model.(options.param_type);
0053 if isempty(parameters)
0054   return
0055 end
0056 
0057 %% 1.0 Propagate through sub-structures
0058 target_types={'fixed_variables','functions','monitors','ODEs','ICs'};
0059 
0060 % loop over types of model data
0061 for type_index=1:length(target_types)
0062   type=target_types{type_index};
0063   
0064   % info for this type
0065   s=model.(type);
0066   if isstruct(s)
0067     update_these=fieldnames(s);
0068     expressions=struct2cell(s);
0069     
0070     % loop over target expressions from which to eliminate internal function calls
0071     for i=1:length(expressions)
0072       if isempty(expressions{i})
0073         continue;
0074       end
0075       
0076       % update expressions of this type
0077       switch options.action
0078         case 'substitute'
0079           expressions{i}=insert_parameters(expressions{i},parameters, [],[], varargin{:});
0080         case 'prepend'
0081           expressions{i}=insert_parameters(expressions{i},parameters, 'prop_prefix',options.prop_prefix, varargin{:});
0082         case 'postpend'
0083           expressions{i}=insert_parameters(expressions{i},parameters, 'prop_suffix',options.prop_suffix, varargin{:});
0084       end
0085     end
0086     
0087     % update model with expressions that have parameter values in them
0088     model.(type)=cell2struct(expressions,update_these,1);
0089   end
0090 end
0091 
0092 %% 2.0 Propagate parameters through structure arrays (conditionals)
0093 if ~isempty(model.conditionals)
0094   target_types={'condition','action','else'};
0095   
0096   for type_index=1:length(target_types)
0097     type=target_types{type_index};
0098     expressions={model.conditionals.(type)};
0099     
0100     % loop over conditional expressions from which to eliminate internal function calls
0101     for i=1:length(expressions)
0102       if isempty(expressions{i})
0103         continue;
0104       end
0105       
0106       % update expressions of this type
0107       switch options.action
0108         case 'substitute'
0109           expressions{i}=insert_parameters(expressions{i},parameters, [],[], varargin{:});
0110         case 'prepend'
0111           expressions{i}=insert_parameters(expressions{i},parameters, 'prop_prefix',options.prop_prefix, varargin{:});
0112         case 'postpend'
0113           expressions{i}=insert_parameters(expressions{i},parameters, 'prop_suffix',options.prop_suffix, varargin{:});
0114       end
0115     end
0116     [model.conditionals(1:length(model.conditionals)).(type)]=deal(expressions{:});
0117   end
0118 end
0119 
0120 
0121 %% auto_gen_test_data_flag argout
0122 if options.auto_gen_test_data_flag
0123   argout = {model}; % specific to this function
0124   
0125   dsUnitSaveAutoGenTestData(argin, argout);
0126 end
0127 
0128 end % main fn
0129 
0130 
0131 %% Local Fn
0132 function expression=insert_parameters(expression,parameters,attachType,attachStr, varargin)
0133 
0134 %% auto_gen_test_data_flag argin
0135 options = dsCheckOptions(varargin,{'auto_gen_test_data_flag',0,{0,1}},false);
0136 if options.auto_gen_test_data_flag
0137   varargs = varargin;
0138   varargs{find(strcmp(varargs, 'auto_gen_test_data_flag'))+1} = 0;
0139   varargs(end+1:end+2) = {'unit_test_flag',1};
0140   argin = [{expression}, {parameters}, {attachType}, {attachStr}, varargs]; % specific to this function
0141 end
0142 
0143 if isnumeric(expression)
0144   % convert to string and return string
0145   expression=toString(expression);
0146   return;
0147 end
0148 
0149 allwords=regexp(expression,'[a-zA-Z]+\w*','match');
0150 words=unique(allwords);
0151 found_parameters=words(ismember(words,fieldnames(parameters)));
0152 
0153 if ~isempty(found_parameters)
0154   % substitute those found into this target expression
0155   for ff=1:length(found_parameters)
0156     % name of found parameter
0157     found_parameter=found_parameters{ff};
0158     
0159     if isempty(attachType) % no prefix given, substitute value instead
0160       % found value to replace found parameter name in target
0161       found_value=parameters.(found_parameter);
0162       
0163       % convert found value into string
0164       if isnumeric(found_value)
0165         if length(found_value)>1
0166           found_value=sprintf('[%s]',num2str(found_value));
0167         else
0168           found_value=num2str(found_value);
0169         end
0170       elseif iscell(found_value)
0171         if iscellstr(found_value)
0172           tmp=cellfun(@(x)['''' x '''' ','] ,found_value,'uni',0);
0173         else
0174           tmp=cellfun(@(x)[num2str(x) ','] ,found_value,'uni',0);
0175         end
0176         tmp=[tmp{:}];
0177         found_value=sprintf('{%s}',tmp(1:end-1));
0178       elseif isa(found_value,'function_handle')
0179         found_value=func2str(found_value);
0180       end
0181     elseif strcmp(attachType, 'prop_prefix') % prefix provided, substitute prefix_name
0182       prefix = attachStr;
0183       found_value=[prefix found_parameter];
0184     elseif strcmp(attachType, 'prop_suffix') % suffix provided, substitute suffix_name
0185       suffix = attachStr;
0186       found_value=[found_parameter suffix];
0187     end
0188     
0189     if ~ischar(found_value)
0190       warning('failed to convert parameter ''%s'' to string and substitute into model equations:',found_parameter);
0191       found_value % TODO: check this
0192     else
0193       % update expression
0194       num_found = length(find(ismember(allwords,found_parameter)));
0195       for iter=1:num_found
0196         if ~strcmp(attachType, 'suffix')
0197           expression=dsStrrep(expression,found_parameter,found_value, '', '', varargin{:});
0198         else
0199           expression=dsStrrep2(expression,found_parameter,found_value, '', '', varargin{:});
0200         end
0201       end
0202     end
0203   end
0204 end
0205 
0206 %% auto_gen_test_data_flag argout
0207 if options.auto_gen_test_data_flag
0208   argout = {expression}; % specific to this function
0209   
0210   dsUnitSaveAutoGenTestDataLocalFn(argin, argout); % localfn
0211 
0212 end
0213 
0214 end

Generated on Tue 12-Dec-2017 11:32:10 by m2html © 2005