V_PARAMSETCH update and check parameter values p=(d,q,m,c,t) Usage: (1) function x=func(y,q) d=struct('a',1,'b',2,'c',3); % default parameters p=v_paramsetch(d,q); % update selected parameters (2) function x=func(y,q) d=struct('a',1,'b',2,'c',3); % default parameters c={'p.a>0 && p.a<5','p.b>0'}; p=v_paramsetch(d,q,'E',c); % check parameter ranges (3) t={'a','description of parameter a';'c','and of parameter c'} p=v_paramsetch(d,q,'l',c,t); % list values with optional descritions % '-','*','+' indicates default, updated and new fields Inputs: d default parameter structure q new parameter values either a struct or alternatively matrix with each row a different variable in the same order as the fields of d m mode string: any combination of the following 'a' include additional fields in q that are not in d 'A' additional fields in q constitute an error 'e' print errors but don't exit 'E' print errors and exit 'l' list fields and their values (default if no output) c cell array with parameter checking conditions e.g. 'p.a>3' (use p for structure name) t cell array with descriptive text for each field in a new row. Either in the form t(:,*)={'field' 'description'} or a single column of descriptions in the same order as the fields of d Outputs: p output parameter structure
0001 function p=v_paramsetch(d,q,m,c,t) 0002 %V_PARAMSETCH update and check parameter values p=(d,q,m,c,t) 0003 % Usage: (1) function x=func(y,q) 0004 % d=struct('a',1,'b',2,'c',3); % default parameters 0005 % p=v_paramsetch(d,q); % update selected parameters 0006 % 0007 % (2) function x=func(y,q) 0008 % d=struct('a',1,'b',2,'c',3); % default parameters 0009 % c={'p.a>0 && p.a<5','p.b>0'}; 0010 % p=v_paramsetch(d,q,'E',c); % check parameter ranges 0011 % 0012 % (3) t={'a','description of parameter a';'c','and of parameter c'} 0013 % p=v_paramsetch(d,q,'l',c,t); % list values with optional descritions 0014 % % '-','*','+' indicates default, updated and new fields 0015 % 0016 % Inputs: 0017 % d default parameter structure 0018 % q new parameter values either a struct or alternatively matrix with 0019 % each row a different variable in the same order as the fields of d 0020 % m mode string: any combination of the following 0021 % 'a' include additional fields in q that are not in d 0022 % 'A' additional fields in q constitute an error 0023 % 'e' print errors but don't exit 0024 % 'E' print errors and exit 0025 % 'l' list fields and their values (default if no output) 0026 % c cell array with parameter checking conditions e.g. 'p.a>3' (use p for structure name) 0027 % t cell array with descriptive text for each field in a new row. Either in 0028 % the form t(:,*)={'field' 'description'} or a single column of 0029 % descriptions in the same order as the fields of d 0030 % 0031 % Outputs: 0032 % p output parameter structure 0033 % 0034 0035 % Copyright (C) Mike Brookes 2017 0036 % Version: $Id: v_paramsetch.m 10865 2018-09-21 17:22:45Z dmb $ 0037 % 0038 % VOICEBOX is a MATLAB toolbox for speech processing. 0039 % Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html 0040 % 0041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0042 % This program is free software; you can redistribute it and/or modify 0043 % it under the terms of the GNU General Public License as published by 0044 % the Free Software Foundation; either version 2 of the License, or 0045 % (at your option) any later version. 0046 % 0047 % This program is distributed in the hope that it will be useful, 0048 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0049 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0050 % GNU General Public License for more details. 0051 % 0052 % You can obtain a copy of the GNU General Public License from 0053 % http://www.gnu.org/copyleft/gpl.html or by writing to 0054 % Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA. 0055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 0056 p=d; % initialize to the default values 0057 numerr=0; % initialize error count 0058 dn=fieldnames(d); % default list of parameter fields 0059 ndn=length(dn); % number of default parameter fields 0060 dup=zeros(ndn,1); % update flags for default fields 0061 % sort out input arguments 0062 if nargin<5 0063 t={'' ''}; % define an empty description array 0064 if nargin<4 0065 c=cell(0); % define an empty check condition array 0066 if nargin<3 0067 m=''; % define an empty mode string 0068 end 0069 end 0070 end 0071 % now update the selected fields 0072 if nargin>1 && numel(q)>0 % if update argument exists 0073 if isstruct(q) % if update argument is a structure 0074 qn=fieldnames(q); % field names to update 0075 addnew=any(m=='a'); % new fields should be added into p 0076 adderr=~addnew && any(m=='A'); % new fields constitute an error 0077 for i=1:length(qn) 0078 fi=qn{i}; 0079 old=isfield(p,fi); % is this an existing field ? 0080 if addnew || old 0081 p.(fi)=q.(fi); 0082 end 0083 if old 0084 dup(find(strcmp(fi,dn),1))=1; % indicate field is updated 0085 end 0086 if adderr && ~old 0087 fprintf(2,'%s is an unknown parameter field\n',fi); 0088 numerr=numerr+1; % increment error count 0089 end 0090 end 0091 else % else update argument is a matrix 0092 nq=min(size(q,1),ndn); % number of fields to update 0093 dup(1:nq)=1; % indicate which fields are updated 0094 for i=1:nq 0095 p.(dn{i})=q(i,:); 0096 end 0097 if size(q,1)>nq && any(lower(m)=='e') 0098 fprintf(2,'More than %d parameters specified\n',nq); 0099 numerr=numerr+1; 0100 end 0101 end 0102 end 0103 % Apply parameter checks 0104 if any(lower(m)=='e') && numel(c)>0 0105 for i=1:numel(c) 0106 if any(~eval(c{i})) 0107 numerr=numerr+1; 0108 fprintf(2,'Parameter check failed: %s\n',c{i}); 0109 end 0110 end 0111 end 0112 % print out a list of the parameters if requested 0113 if ~nargout || any(m=='l') 0114 pn=fieldnames(p); 0115 nf=length(pn); 0116 st=size(t); 0117 for i=1:nf 0118 fi=pn{i}; 0119 vi=p.(fi); 0120 if i>ndn 0121 cat='+'; 0122 else 0123 cat='-'+('*'-'-')*dup(i); 0124 end 0125 if st(2)>1 0126 jti=find(strcmp(fi,t(:,1)),1); 0127 if ~isempty(jti) 0128 jti=t{jti,2}; % description string 0129 end 0130 elseif i<=st(1) 0131 jti=t{i,1}; % description string 0132 else 0133 jti=[]; 0134 end 0135 if isnumeric(vi) && length(vi)==numel(vi) && isreal(vi) % can print on one line 0136 fit=fi; 0137 if size(vi,1)>1 0138 fit=[fi '''']; 0139 end 0140 fprintf('%3d%c %s =',i,cat,fit); 0141 fprintf(' %g',vi); 0142 if isempty(jti) 0143 fprintf('\n'); 0144 else 0145 fprintf(' = %s\n',jti); 0146 end 0147 else 0148 fprintf('%3d%c %s =',i,cat,fi); 0149 if isempty(jti) 0150 fprintf('\n'); 0151 else 0152 fprintf(' %s =\n',jti); 0153 end 0154 disp(vi); 0155 end 0156 end 0157 end 0158 if numerr>0 && any(m=='E') 0159 error('%d error%c in parameter specification',numerr,(' '+(numerr>1)*('s'-' '))); 0160 end