2013-12-10 3 views
5

Я использую Octave и хотел бы векторизовать функцию, которая принимает в качестве входного единственного действительного числа и выводит вектор строки фиксированной длины. Я понимаю, что arrayfun должен быть в состоянии сделать это из своей нечеткой документации. Из help arrayfun в Octave 3.2:Функция векторизации, которая выводит строку с использованием arrayfun, возвращая матрицу

If the parameter VAL after a further string input argument "UniformOutput" is set 'true' (the default), then the named function FUNC must return a single element which then will be concatenated into the return value and is of type matrix. Otherwise, if that parameter is set to `false', then the outputs are concatenated in a cell array.

Кажется, однако, что Matlab's version is more forgiving:

[B1,...,Bm] = arrayfun(func,A1,...,An) calls the function specified by function handle func and passes elements from arrays A1,...,An, where n is the number of inputs to function func. Output arrays B1,...,Bm, where m is the number of outputs from function func, contain the combined outputs from the function calls. The ith iteration corresponds to the syntax [B1(i),...,Bm(i)] = func(A1{i},...,An{i}). The arrayfun function does not perform the calls to function func in a specific order.

Похоже, это работает в Matlab, но не в октаву. Правильно ли, что это обобщение не может быть выполнено с использованием arrayfun в Octave? Есть ли еще более умный способ достичь этого, не прибегая к неветвированным петлям?

Для справки, вот мой Октав результат:

octave:5> nums
nums =

@(c) ([c, c + 2, c + 4])

octave:6> arrayfun(nums,[1,2,3])
error: cellfun: expecting all values to be scalars for UniformOutput = true
error: called from:
error: /opt/local/share/octave/3.2.4/m/general/arrayfun.m at line 168, column 21
octave:6>

+0

Почему вы настаиваете на 'arrayfun'? попробуйте простой цикл 'for' и сделайте с ним. – Shai

+0

@Shai http://en.wikipedia.org/wiki/Vectorization_(parallel_computing) – djechlin

+0

@djechlin: http://stackoverflow.com/questions/12522888/arrayfun-can-be-significantly-slower-than-an-explicit -loop-in-matlab-why – Daniel

ответ

0

ошибка уже показывает, как решить эту проблему:

arrayfun(nums,[1,2,3],'UniformOutput',false) 

Там нет никакой разницы между Matlab и Octave.

Matlab:

>> [email protected](c) ([c, c + 2, c + 4]) 

nums = 

    @(c)([c,c+2,c+4]) 

EDU>> arrayfun(nums,[1,2,3]) 
Error using arrayfun 
Non-scalar in Uniform output, at 
index 1, output 1. 
Set 'UniformOutput' to false. 

>> arrayfun(nums,[1,2,3],'UniformOutput',false) 

ans = 

    Columns 1 through 2 

    [1x3 double] [1x3 double] 

    Column 3 

    [1x3 double] 

Октава:

octave:1> [email protected](c) ([c, c + 2, c + 4]) 
nums = 

@(c) ([c, c + 2, c + 4]) 

octave:2> arrayfun(nums,[1,2,3]) 
error: arrayfun: all values must be scalars when UniformOutput = true 
octave:2> arrayfun(nums,[1,2,3],'UniformOutput',false) 
ans = 
{ 
    [1,1] = 

    1 3 5 

    [1,2] = 

    2 4 6 

    [1,3] = 

    3 5 7 

} 
octave:3> 

Если ваша функция действительно просто, я предлагаю использовать:

nums([1,2,3]') 
+0

К сожалению, мои фактические 'nums' немного сложнее. Это больше похоже на 'nums = @ (c) (other_function (c, curried_argument))'. Я думаю, именно поэтому ваше последнее решение ломается. Да, я мог бы отключить UniformOutput и преобразовать результат, который, возможно, является самым изящным делом, но все еще исследует. – djechlin

+0

@djechlin, тогда, если это возможно, вам следует подумать о написании 'other_function', чтобы принять векторы. – carandraug

+0

@ carandraug Я этого не знаю. (Это 'fmincg'.) – djechlin

2

Используйте arrayfun применить функцию, nums к массиву [1,2,3]

CellArray = arrayfun(nums, [1,2,3], "UniformOutput", false); 

Это дает вам массив ячеек. Если вы хотите, чтобы ответ в матрице, используйте cell2mat

cell2mat(CellArray); 

Если фактическая nums является более сложным, то нам понадобится лучший пример этого, чтобы предложить решение.

+0

' arrayfun' с '' UniformOutput ', false' возвращает массив ячеек строки (т. Е. Вдоль второго измерения). И выходы 'nums' также являются векторами строк (т. Е. Вдоль второго измерения). «Cell2mat» объединяет их как вектор длинной строки. Чтобы получить матрицу, сначала измените массив ячеек на ожидаемый размер конкатенации: 'cell2mat (reshape (CellArray, numel (CellArray), 1))' – ederag

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