这是All possible combinations of many parameters MATLAB问题的后续行动
除了我的参数集的所有可能组合,我还有一个条件参数。例如,我只需要在参数'corrAs'设置为'objective'时包含名为'lambda'的参数。
要做到这一点,现在我正在做以下事情
%% All posible parameters
params.corrAs = {'objective', 'constraint'};
params.size = {'small', 'medium', 'large'};
params.density = {'uniform', 'non-uniform'};
params.k = {3,4,5,6};
params.constraintP = {'identity', 'none'};
params.Npoints_perJ = {2, 3};
params.sampling = {'hks', 'fps'};
% If corrAs is 'objective', then also set lambda
params.lambda = {0.01, 0.1, 1, 10, 100};
%%%%%%%%%%%%% The solution posted on the link %%%%%%%%%%%
%% Get current parameter and evaluate
fields = fieldnames(params);
nFields = numel(fields);
sz = NaN(nFields, 1);
% Loop over all parameters to get sizes
for jj = 1:nFields
sz(jj) = numel( params.(fields{jj}) );
end
% Loop for every combination of parameters
idx = cell(1,nFields);
for ii = 1:prod(sz)
% Use ind2sub to switch from a linear index to the combination set
[idx{:}] = ind2sub( sz, ii );
% Create currentParam from the combination indices
currentParam = struct();
for jj = 1:nFields
%%%%%%%%%%% My addition for conditional parameter %%%%%%%%%%%
% lambda is valid only when corrAs is 'objective'
if isfield(currentParam, 'corrAs') && strcmp(fields{jj}, 'lambda') && ~strcmp(currentParam.corrAs, 'objective')
continue;
end
currentParam.(fields{jj}) = params.(fields{jj}){idx{jj}};
end
%% Do something with currentParam
end
它工作但是,主for循环的迭代次数也包括lambda参数,即使corrAs不是'客观'。所以,我最终用相同的currentParam进行多次评估。
我怎样才能更有效率地做到这一点?
考虑这一点的简单方法是将代码分解为更基于功能
在下面的代码中,我只是将组合处理代码放入函数paramProcessing
中。这个函数被调用两次 -
params.corrAs
仅为'constraint'
时,将处理所有组合,没有lambda
字段。params.corrAs
仅为'objective'
时,所有组合将使用额外的lambda
字段进行处理。如果循环中有一个输出,则可以为paramProcessing
函数输出。
这意味着您只需要进行所需的组合。从您的问题来看,似乎每个组合都是独立的,因此您在单独的循环中覆盖组合应该是无关紧要的。函数用法意味着您不必在循环中具有新条件,并且每次params.corrAs
的不同可能值确保不重叠。
paramProcessing
函数可以是主函数文件中的本地函数,如图所示,脚本中的本地函数(对于较新的MATLAB版本),或者在路径中的自己的.m文件中。
码:
function main()
%% All posible parameters, corrA is 'constraint' only.
params.corrAs = {'constraint'};
params.size = {'small', 'medium', 'large'};
params.density = {'uniform', 'non-uniform'};
params.k = {3,4,5,6};
params.constraintP = {'identity', 'none'};
params.Npoints_perJ = {2, 3};
params.sampling = {'hks', 'fps'};
% First processing call, no 'lambda' field exists in 'params'
paramProcessing( params );
% Cover the cases where corrAs is 'objective', with 'lambda' field
params.corrAs = {'objective'};
params.lambda = {0.01, 0.1, 1, 10, 100};
% Second processing call, with new settings
paramsProcessing( params );
end
function paramProcessing( params )
%% Get current parameter and evaluate
fields = fieldnames(params);
nFields = numel(fields);
sz = NaN(nFields, 1);
% Loop over all parameters to get sizes
for jj = 1:nFields
sz(jj) = numel( params.(fields{jj}) );
end
% Loop for every combination of parameters
idx = cell(1,nFields);
for ii = 1:prod(sz)
% Use ind2sub to switch from a linear index to the combination set
[idx{:}] = ind2sub( sz, ii );
% Create currentParam from the combination indices
currentParam = struct();
for jj = 1:nFields
currentParam.(fields{jj}) = params.(fields{jj}){idx{jj}};
end
%% Do something with currentParam
end
end