我有一个参数列表,我需要在该列表上评估我的方法。现在,我正在这样做
% 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
答案 0 :(得分:5)
您需要的是all combinations个输入参数。不幸的是,随着添加更多参数,存储需求将迅速增长(并且您将不得不使用大型索引矩阵)。
相反,这是一个使用(从未创建的)function find(object, value) {
return Object
.keys(object)
.find(k => [].concat(object[k]).includes(value));
}
var object = { FOO: { BAR: [9, 32, 8, 12], ZET: 4, BETA: [3, 14, 6, 2], ALPHA: 37 } };
console.log(find(object.FOO, 4));
console.log(find(object.FOO, 8));
矩阵的线性索引的想法,其中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
传递multiple outputs into a cell array,所以当ind2sub
每个维度(或本用例中的字段)有一个输出时,您可以处理可变数量的字段名称。答案 1 :(得分:3)
这是向量化的解决方案:
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
来创建单元格条目的笛卡尔积,而不是嵌套循环,因此我们可以找到没有循环的所有单元格条目组合。