有条件地选择MATLAB

时间:2019-01-08 18:59:24

标签: matlab struct combinations

这是问题All possible combinations of many parameters MATLAB的后续内容

除了参数集的所有可能组合之外,我还有一个条件参数。例如,仅当参数“ corrAs”设置为“目标”时,才需要包含名为“ 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

它可以工作,但是即使在corrAs不是“目标”时,main for循环的迭代次数也包括lambda参数。因此,我最终使用同一个currentParam进行评估的次数比我预期的要多。

我如何才能更有效地做到这一点?

1 个答案:

答案 0 :(得分:0)

考虑这一点的一种简单方法是将代码分解为更多基于功能的

在下面的代码中,我仅将组合处理代码放入了函数paramProcessing中。 该函数被调用了两次-

  1. 仅当params.corrAs'constraint'时,将处理所有组合,而没有lambda字段。

  2. 仅当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