【问题标题】:All possible combinations of many parameters MATLAB许多参数的所有可能组合 MATLAB
【发布时间】:2019-01-07 10:15:10
【问题描述】:

我有一个参数列表,我需要在这个列表中评估我的方法。现在,我就是这样做的

% 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'};   

% Select the current parameter
for corrAs_iter = params.corrAs
    for size_iter = params.size
        for density_iter = params.density
            for k_iter = params.k
                for constraintP_iter = params.constraintP
                    for Npoints_perJ_iter = params.Npoints_perJ
                        for sampling_iter = params.sampling
                            currentParam.corrAs = corrAs_iter;
                            currentParam.size = size_iter;
                            currentParam.density = density_iter;
                            currentParam.k = k_iter;
                            currentParam.constraintP = constraintP_iter;
                            currentParam.Npoints_perJ = Npoints_perJ_iter;
                            currentParam.sampling = sampling_iter;
                            evaluateMethod(currentParam);
                        end
                    end
                end
            end
        end
    end
end

我知道它看起来很难看,如果我想添加一种新类型的参数,我必须编写另一个 for 循环。有什么办法,我可以矢量化这个吗?或者也许使用 2 个 for 循环而不是这么多。

我尝试了以下方法,但没有得到我需要的结果。

for i = 1:numel(fields)
%     if isempty(params.(fields{i}))
    param.(fields{i}) = params.(fields{i})(1);
    params.(fields{i})(1) = [];
end

【问题讨论】:

标签: matlab struct


【解决方案1】:

您需要的是all combinations 的输入参数。不幸的是,随着您添加更多参数,存储需求将迅速增长(并且您必须使用大型索引矩阵)。

相反,这是一个使用(从未创建的)n1*n2*...*nm 矩阵的线性索引的想法,其中ni 是每个字段中的元素数,对于m 字段。

它足够灵活,可以处理添加到params 的任意数量的字段。未经性能测试,尽管与任何“所有组合”操作一样,当您向params 添加更多字段时,您应该警惕计算时间的非线性增加,注意prod(sz)

我展示的代码很快,但性能完全取决于您在循环中执行的操作。

% Add parameters here
params.corrAs = {'objective', 'constraint'};
params.size = {'small', 'medium', 'large'};
params.density = {'uniform', 'non-uniform'};

% Setup
f = fieldnames( params );
nf = numel(f);
sz = NaN( nf, 1 );

% Loop over all parameters to get sizes
for jj = 1:nf
    sz(jj) = numel( params.(f{jj}) );
end

% Loop for every combination of parameters
idx = cell(1,nf);
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:nf
        currentParam.(f{jj}) = params.(f{jj}){idx{jj}};
    end
    % Do something with currentParam here
    % ...
end

旁白:

【讨论】:

  • 谢谢,是否可以合并条件字段。例如,如果 strcmp(currentParam.corrAs, 'objective') currentParam.lambda = 100; % 但是,从 params.lambda = {1, 10, 100, 1000};结束
  • @zee 这有点不清楚,也许你可以用你想要的输出提出一个新问题
  • 请在stackoverflow.com/q/54098049/5984672找到后续问题
【解决方案2】:

这是一个矢量化的解决方案:

names = fieldnames(params).';
paramGrid = cell(1,numel(names));

cp = struct2cell(params);

[paramGrid{:}] = ndgrid(cp{:});

ng = [names;paramGrid];
st = struct(ng{:});


for param = st(:).'
    currentParam = param;
end

我们可以使用ndgrid 来代替嵌套循环来创建单元格条目的笛卡尔积,这样我们就可以找到没有循环的单元格条目的所有组合。

【讨论】:

    猜你喜欢
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多