2014-02-15 3 views
3

Я пытаюсь написать код, который передает функцию с неизвестным количеством параметров. Идея состоит в том, чтобы подавать функцию минимальное, среднее и максимальное значение в пределах возможного диапазона значений.Выполнение всех возможных перестановок входных параметров (логика двоичного стиля)

Например:

  • Если функция принимает 3 параметра
  • Параметр 1 может принимать целый ряд 0 - 10
  • Параметр 2 может принимать диапазон 20 - 40
  • Параметр 3 может принимать целый ряд 6 - 66

MyFunction (para1, para2, para3)
myfun фикция (мин, мин, мин)
MyFunction (мин, не менее, в середине)
MyFunction (мин, мин, макс)
MyFunction (мин, в середине, мин)
MyFunction (мин, в середине, в середине)
MyFunction (мин, средняя, ​​максимальная)
и т.д ...

так, используя наш пример выше:

в первый раз это петли мне нужно запустить
MyFunction (0, 20, 0)
в следующий раз, когда он петли, ему нужно запустить
MyFunction (0, 20, 36)
следующий раз петли он должен запустить
MyFunction (0, 20, 66)
и т.д. ...

Для всех возможных комбинаций (в данном случае все 27).
Однако, если число параметров изменяется, чтобы принять 4, оно должно быть способным принять это и так далее. Я смотрел на это как на цикл или рекурсивно, но я думал, что цикл будет легче понять, но это будет очень полезно.

Я не хочу, чтобы это делать вручную, поэтому любая помощь будет высоко оценена.

+0

см [ 'varargin'] (http://www.mathworks.com/help/matlab/ref/varargin.html). –

ответ

3

Для произвольное количество параметров (не фиксировано до 3), вы можете использовать следующий код. Он использует comma-separated lists, который является мощным инструментом для обработки переменного количества параметров.

Пусть n - количество параметров.Тогда число комбинаций равно N = 3^n.

params = {linspace(0,10,3), linspace(20,40,3), linspace(6,66,3)}; 
%// cell array with arbitrary number of elements. Each cell contains a 3-vector 
%// which defines min, mid, max of one parameter. 

n = numel(params); %// number of parameters 
N = 3^n; %// number of combinations 
paramCombs = cell(1,n); %// initialization for output of ndgrid 
[paramCombs{end:-1:1}] = ndgrid(params{end:-1:1}); %// generate all combinations 
%// in desired order. Gives n matrices, each containing values of one parameter 
paramCombs = cellfun(@(c) c(:), paramCombs, 'uni', 0); %// linearize matrices 
%// into n column vectors, each with N rows. 
paramCombs = [paramCombs{:}]; %// concat column vectors into N x n matrix 
paramCombs = mat2cell(paramCombs,ones(N,1),ones(n,1)); %// convert to 
%// N x n cell array. Each row contains a combination of parameter values 
result = arrayfun(@(n) myFun(paramCombs{n,:}), 1:N, 'uni', 0); %// call myFun 
%// with each combination of parameter values 

Переменная result является массивом N ячейки 1 х, где каждая ячейка содержит результат вызова myFun с комбинацией из п параметров.

Пример 1: выход myFun «ы просто повторяет входной сигнал (как и в @thewaywewalk's answer). params определен, как указано выше, таким образом, есть 3 параметра:

>> result{1} 
ans = 
    0 20  6 
>> result{2} 
ans = 
    0 20 36 
>> result{3} 
ans = 
    0 20 66 
>> result{4} 
ans = 
    0 30  6 
>> result{5} 
ans = 
    0 30 36 

т.д.

Пример 2: корпус с 2-мя параметрами: params = {linspace(0,2,3), linspace(0,10,3)}. Опять же, myFun просто повторяет вход:

>> result{1} 
ans = 
    0  0 
>> result{2} 
ans = 
    0  5 
>> result{3} 
ans = 
    0 10 
>> result{4} 
ans = 
    1  0 
>> result{5} 
ans = 
    1  5 

т.д.

Способ может быть дополнительно к обобщенным произвольной (и, возможно, другой) число значений для каждого параметра, просто заменив линию N = 3^n; по

N = prod(cellfun(@numel, params)); %// number of combinations 

Пример 3: есть 2 параметра; первое с 3-х значений, а второй с 2: params = {[1 2 3], [10 20]};:

>> result{1} 
ans = 
    1 10 
>> result{2} 
ans = 
    1 20 
>> result{3} 
ans = 
    2 10 
>> result{4} 
ans = 
    2 20 
>> result{5} 
ans = 
    3 10 
>> result{6} 
ans = 
    3 20 
3

Подумайте о чем-то вроде этого:

function result = permfunction() 

% I assume you every parameter-range is defined by 3 values: min, mid, max 
% you can define every triple as follows: 
para1 = linspace(0,10,3); 
para2 = linspace(20,40,3); 
para3 = linspace(6,66,3); 

% all possible parameters 
parameters = [para1(:),para2(:),para3(:)]; 

% possible combinations of parameters-indices 
a = perms(1:3); 
% transformed into a cell array with linear indices, to achieve this +3 and +6 
% are added to the 2nd and 3rd row. 

idx = mat2cell([a(:,1) , a(:,2)+3 , a(:,3)+6] , ones(length(a),1)); 

% all parameter combinations 
combinations = cellfun(@(x) parameters(x),idx,'uni',0'); 

% apply to your function myfunction (custom) 
result = cellfun(@myfunction, combinations,'uni',0'); 

end 

function y = myfunction(parametertriple) 

%just pass the input to the output 
y = parametertriple; 

end 

вы, наконец, получить массив ячеек с результатами MyFunction для всех комбинаций параметров. В этом случае, я только что прошел параметры на выходе:

>> celldisp(ans) 

ans{1} = 

    10 30  6 

ans{2} = 

    10 20 36 

ans{3} = 

    5 40  6 

ans{4} = 

    5 20 66 

ans{5} = 

    0 30 66 

ans{6} = 

    0 40 36 
+0

+1 Хороший подход. Может быть обобщен на неопределенное количество параметров с помощью разделенных запятыми списков; см. мой ответ –

0

Это, как я бы решить:

%dummy function 
[email protected](a,b,c)fprintf('call function for %d,%d,%d\n',a,b,c); 
%functon name 
testfunname='testfun'; 
%intended inputs 
input={[0,5,10],[20,30,40],[6,36,66]}; 
%generate all inputs 
eval(['[' sprintf('a{%d} ',1:numel(input)) ']=meshgrid(input{:});']); 
%call function 
eval(['arrayfun(' testfunname sprintf(',a{%d} ',1:numel(input)) ');']); 

Использование eval грязное решение, но я не найти альтернативу, которая позволяет изменять размер входного файла.

Смежные вопросы