2013-11-15 1 views
2

Меня интересует вычисление функции на множестве перестановок значений параметров. Я хочу сохранить его общим для N измерений, но позвольте мне записать его в трех измерениях. Генерирование перестановок достаточно просто с meshgrid, но я не могу понять, как изменить полученный результирующий массив на многомерности? Вот отправная точка:Перестановки параметров (т. Е. Декартово произведение) в многомерный массив

%These are the 3 variations of parameters, with some values. 
params1 = [100, 200, 300];%Picking these so it is easy to correlate to the function 
params2 = [10, 20]; 
params3 = [1, 2]; 

%This generates parameter_values as the cartesian productpermutations. 
[vec1, vec2, vec3] = meshgrid(params1, params2, params3); 
parameter_values = [vec1(:) vec2(:) vec3(:)]; 

%Calculates functions on the set of parameters. 
%Would have a fancier function, of course, this just makes it easy to see the results. 
raw_vals = parameter_values(:,1) + parameter_values(:,2) + parameter_values(:,3); 

%Rearrange into a multiarray to access by parameter indices. 
f_vals = reshape(raw_vals, [length(params1), length(params2), length(params3)]) %WRONG? 

%THE FOLLOWING FAIL BUT WOULD BE EXPECTED WITH THESE PARAMETERS AND THE FUNCTION. 
assert(f_vals(2,1,1) == 211) 
assert(f_vals(3,2,2) == 322) 
+0

Может 'raw_values' устройств изменит такого же размера, как' vec1', '' vec2' или vec3'? – David

ответ

4

Вы хотите ndgrid вместо meshgrid в этом случае.

meshgrid синтаксис [X,Y] = meshgrid(xgv,ygv), который вызывает Y(:), чтобы варьироваться быстрее, чем X(:). См. Gridded Data Representation для более подробной информации. Другими словами, вы получаете

>> [vec1, vec2, vec3] = meshgrid(params1, params2, params3) 
vec1(:,:,1) = 
    100 200 300 
    100 200 300 
vec1(:,:,2) = 
    100 200 300 
    100 200 300 
vec2(:,:,1) = 
    10 10 10 
    20 20 20 
vec2(:,:,2) = 
    10 10 10 
    20 20 20 
... 

Но вы хотите получать:

>> [vec1, vec2, vec3] = ndgrid(params1, params2, params3) 
vec1(:,:,1) = 
    100 100 
    200 200 
    300 300 
vec1(:,:,2) = 
    100 100 
    200 200 
    300 300 
vec2(:,:,1) = 
    10 20 
    10 20 
    10 20 
vec2(:,:,2) = 
    10 20 
    10 20 
    10 20 
... 

При переключении на ndgrid, то вы получите f_vals(2,1,1) == 211, как предполагалось.

Обобщая до N-измерений можно было бы сделать так:

params = {[100, 200, 300],[10, 20],[1, 2]}; 
    vecs = cell(numel(params),1); 
    [vecs{:}] = ndgrid(params{:}); 
    parameter_values = reshape(cat(numel(vecs)+1,vecs{:}),[],numel(vecs)); 
    raw_vals = sum(parameter_values,2); 
    f_vals = reshape(raw_vals,cellfun(@numel,params)) 
+0

Это сделало, спасибо. 'meshgrid' уверен, что имеет странное поведение для> 2 параметров. – jlperla

+0

@jlperla - Рад, что сделал это. Код N-dim довольно компактный, попробуйте его. Существуют некоторые сложные методы работы с ячейками и запятыми, но я думаю, что он обобщен, по крайней мере, для измерения> 1. – chappjc

+2

Теперь это действительно так! Код был полностью обобщен и прошел мой регрессионный тест, и я узнал кое-что о вариативных функциях в Matlab, когда был на нем. – jlperla