Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vectorize function that outputs a row using arrayfun, returning a matrix

I'm using Octave and would like to vectorize a function that accepts as input a single real number and outputs a row vector of fixed length. I understand that arrayfun should be able to do this from its unclear documentation. From help arrayfun in Octave 3.2:

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.

It seems however that 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.

It looks like this works in Matlab but not in Octave. Am I correct that this generalization cannot be performed using arrayfun in Octave? Is there some more clever way to achieve this without resorting to unvectorized loops?

For reference, here is my Octave result:

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>

like image 542
djechlin Avatar asked Dec 10 '13 16:12

djechlin


People also ask

What does arrayfun do in Matlab?

arrayfun returns the outputs of func in cell arrays. The outputs of func can have any sizes and different data types.

What does the function all () do in Matlab?

The all function reduces such a vector of logical values to a single condition. In this case, B = all(A < 0.5) yields logical 0 . This makes all particularly useful in if statements. The code is executed depending on a single condition, rather than a vector of possibly conflicting conditions.


2 Answers

Use arrayfun to apply the function, nums to an array [1,2,3]

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

That gives you a cell array. If you want the answer in a matrix, use cell2mat

cell2mat(CellArray);

If your actual nums is more complicated, then we'll need a better example of it to suggest a solution.

like image 192
Charity Leschinski Avatar answered Sep 29 '22 11:09

Charity Leschinski


The error already suggests how to solve the problem:

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

There is no difference between Matlab and Octave.

Matlab:

>> nums=@(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:

octave:1> nums=@(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> 

If your function is really that simple, I suggest to use:

nums([1,2,3]')
like image 45
Daniel Avatar answered Sep 29 '22 11:09

Daniel