简体   繁体   English

在MATLAB中条件选择所有可能的参数组合

[英]Conditional selection of all possible parameter combinations in MATLAB

This is a follow-up of the question All possible combinations of many parameters MATLAB 这是一个问题的后续问题所有可能的MATLAB参数组合

In addition to all possible combinations of my parameter set, I also have a conditional parameter. 除了我的参数集的所有可能组合,我还有一个条件参数。 For example, I need to include the parameter named 'lambda' only when the parameter 'corrAs' is set to 'objective'. 例如,我只需要在参数'corrAs'设置为'objective'时包含名为'lambda'的参数。

Do achieve this, right now I am doing the following 要做到这一点,现在我正在做以下事情

%% 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

It works but, the number of iterations for the main for loop also includes the lambda parameter even when corrAs is not 'objective'. 它工作但是,主for循环的迭代次数也包括lambda参数,即使corrAs不是'客观'。 So, I end up evaluating with the same currentParam many times than I am supposed to. 所以,我最终用相同的currentParam进行多次评估。

How can I do it more efficiently? 我怎样才能更有效率地做到这一点?

An easy way to think about this is by breaking the code up to be more function-based 考虑这一点的简单方法是将代码分解为更基于功能

In the below code, I've simply put the combination processing code into a function paramProcessing . 在下面的代码中,我只是将组合处理代码放入函数paramProcessing This function is called twice - 这个函数被调用两次 -

  1. When params.corrAs is 'constraint' only, all combinations will be processed, with no lambda field. params.corrAs只是'constraint' ,将处理所有组合,没有lambda字段。

  2. When params.corrAs is 'objective' only, all combinations will be processed with the additional lambda field. params.corrAs 'objective' ,将使用附加的lambda字段处理所有组合。

You can have an output for the paramProcessing function if there is one from the looping. 如果循环中存在一个输出, paramProcessing函数提供输出。

This means you're only doing the combinations you want. 这意味着您只需要进行所需的组合。 From your question, it seems like each combination is independent, so it should be irrelevant that you're covering the combinations in separate loops. 从您的问题来看,似乎每个组合都是独立的,因此您在单独的循环中覆盖组合应该是无关紧要的。 The function usage means you don't have to have the new condition in the loop, and the distinct possible values for params.corrAs each time ensure no overlap. 函数用法意味着您不必在循环中具有新条件,并且每次params.corrAs的不同可能值确保不重叠。

The paramProcessing function can be a local function in a main function file, as shown, local in a script (for newer MATLAB versions), or in its own .m file on your path. paramProcessing函数可以是主函数文件中的本地函数,如图所示,脚本中的本地函数(对于较新的MATLAB版本),或者在路径中的自己的.m文件中。

Code: 码:

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    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM