arrayfun when each row of the array is an input - matlab

My situation is that I would like to map a scalar array A by a function with handle fun sending a row vector to a row vector, to acquire B, such that B(i,:) = fun(A(i,:)).
The most reasonable solution I could think of looks like:
temp = mat2cell(A,ones(1,size(A,1)),size(A,2));
B = cell2mat(cellfun(fun,temp,'UniformOutput',0));
However, the conversion to cells and back seems like overkill (and is assumably computationally expensive). It is also not clear to me why cellfun complains about non-uniform output. Does a more efficient way jump to mind?

There's another solution that employs accumarray. Although not as fancy as bsxfun, it doesn't require declaring a helper function:
subs = ndgrid(1:size(A, 1));
B = accumarray(subs(:), A(:), [], #fun); %// #fun is the function handle

You can do this without using cell arrays at all with bsxfun.
Using Marcin's example data and function:
A =[ 0.5669 0.4315 0.4515 0.7664 0.5923; ...
0.8337 0.7317 0.4898 0.2535 0.7506; ...
0.3321 0.5424 0.4585 0.8004 0.9564];
fun = #(x,y) x*2;
B= bsxfun(fun,A,1);
B =
1.1338 0.8630 0.9030 1.5328 1.1846
1.6674 1.4634 0.9796 0.5070 1.5012
0.6642 1.0848 0.9170 1.6008 1.9128
Edit:
As Eitan noted, fun above may need to be a wrapper on your 'real' anonymous function so it would be more complete to show my solution as:
fun = #(x) x *2; % Replace with actual anonymous function
fun2 = #(x,y) fun(x); % Wrapper on fun to discard unused 2nd parameter
B= bsxfun(fun2,A,1);

I know this is an old post, but in case someone else sees this, Matlab added rowfun to the 2013b release which can evaluate rows of tables and returns a column vector. Here is an example:
f = #(c) sum(c.^2);
x=[1 2;
3 4;
5 6];
z=table2array(rowfun(f,table(x)))
z=
5
25
61

I think you could do as follows, if I understand what u want to do:
A = rand(3, 5);
fun = #(x) x*2;
B = cell2mat(arrayfun(#(i) fun(A(i, :)), 1:size(A, 1), 'UniformOutput', false)');
% example results:
A =
0.5669 0.4315 0.4515 0.7664 0.5923
0.8337 0.7317 0.4898 0.2535 0.7506
0.3321 0.5424 0.4585 0.8004 0.9564
B =
1.1338 0.8630 0.9030 1.5328 1.1845
1.6675 1.4635 0.9795 0.5071 1.5013
0.6642 1.0848 0.9169 1.6008 1.9128
This will apply fun to each element of row in A. This is based on the post here. Also there u find more info and explanation what is happening or alternative ways of applying function to rows in an array.

Related

Matlab: make a matrix by looping through an index without using a For loop?

I have a function A(k) which returns a matrix dependent on k when I type for example A(1). I want to automatically create the matrix:
[A(3)*A(2)*A(1) A(3)*A(2) A(3)]
In Mathematica I can do for example:
Table[Apply[Dot,Table[A(k),{k,3,i,-1}]],{i,1,3}]
Assume A(k) is a function which returns a 3x3 matrix. For example typing A(1) may return:
[1,2,3;4,5,6;7,8,9]
Explanation of Mathematica code: Table[A(k),{k,3,i,-1}] is a "loop" from k=3 to k=i with each iteration decrementing k by -1. Therefore the output would be a list {A(3),A(2),...,A(i)}... obviously k starting from 3 then for i=2 the output list will be {A(3),A(2)}. The function Apply[Dot,Table[A(k),{k,3,i,-1}]] multiplied the elements of the list together. For i=2 this produces A(3)*A(2). Finally, Table[Apply[Dot,Table[A(k),{k,3,i,-1}]],{i,1,3}] applies the same logic as the first statement, looping i from 1 to 3. Because the inner table depends on i, this creates a list of elements {A(3)*A(2)*A(1),A(3)*A(2),A(3)}. A list is Mathematica's version of a matrix.
How can I achieve the same effect in MATLAB, i.e. not use a for loop to achieve the result? Thanks!
For the record, here's a looping version, mostly for subsequent timing checks. This is not the answer you want, but the answer you need;)
N = 10; %size of A
old = eye(N);
M2 = [];
for i=3:-1:1
new = old*A(i);
M2 = [new M2];
old = new;
end
Or if you want to be really efficient (which is probably not the case):
N = 10; %size of A
M2 = A(3);
old = M2;
for i=2:-1:1
new = old*A(i);
M2 = [new M2];
old = new;
end
This answer basically is the solution to the problem, but as we are discussing efficient use of matlab I want to leave my thoughts here how to use Matlab efficient. Instead of the large 2D-Matrix it is much simpler to create a 3D-Matrix where the results of each multiplication are stacked. If a 3D-Matrix is acceptable use the code as it is, otherwise comment in the last line to get a 2D-matrix.
M3=[];
n=3;
M3(:,:,n) = A(n);
for ix=n-1:-1:1
M3(:,:,ix) = M3(:,:,ix+1)*A(i);
end
%M3=reshape(M3,size(M3,1),[]);
You can use arrayfun() with indexes as parameters, eg:
%// Compute the product A(3)*A(2)*...*A(idx)
F = #(idx) prod(reshape(cell2mat(arrayfun(A,3:-1:idx, 'UniformOutput', false)),10,10,4-idx),3);
%// Use the last function with idx=1:3
M = cell2mat(arrayfun(F,1:3, 'UniformOutput', false));

Derivative of Anonymous Function

I have the following anonymous function:
f = #(x)x^2+2*x+1
I'm using this so that I use it in the following way:
f(0) = 1
But what if I want to find the derivative of such a function while still keeping it's anonymous function capability? I've tried doing the following but it doesn't work:
f1 = #(x)diff(f(x))
but this just returns
[]
Any thoughts on how to accomplish this?
Of course I could manually do this in 3 seconds but that's not the point...
If you have symbolic math toolbox, you can use symbolic functions to achieve the desired as follows:
syms x
myFun=x^2+2*x+1;
f=symfun(myFun,x);
f1=symfun(diff(f),x);
%Check the values
f(2)
f1(2)
You should get 9 and 6 as answers.
When you do diff of a vector of n elements it just outputs another vector of n-1 elements with the consecutive differences.. so when you put a 1 element vector you get an empty one.
A way to go would be to decide an epsilon and use the Newton's difference quotient:
epsilon = 1e-10;
f = #(x) x^2+2*x+1;
f1 = #(x) (f(x+epsilon) - f(x)) / epsilon;
or just do the math and write down the formula:
f1 = #(x) 2*x+2;
http://en.wikipedia.org/wiki/Numerical_differentiation
#jollypianoman this works to me. Actually you need to say that the symfun has to be evaluate using eval command, then you get all the features of an anonymous function. the best is to read the example below...
clear
N0=1;N1=5;
N=#(t) N0+N1*sin(t);
syms t
Ndot=symfun(diff(N(t)),t);
Ndot_t=#(t) eval(Ndot);
Ndot_t(0)
ans = 5
Ndot_t(1)
ans = 2.7015
[tstop] = fsolve(Ndot_t,pi/3)
tstop =
1.5708
cheers,
AP

Using `bsxfun` for non-numeric data

Is there an equivalent to bsxfun for non-numeric data?
For example, I want to compare all pairs of strings stored in two cell-arrays:
>> a = {'aa', 'bb', 'cc'};
>> b = {'dd', 'aa'};
>> bsxfun( #strcmp, a, b' ); % not working for cells :-(
I like Rody's solution, but you could also do a workaround like this:
ia=(1:length(a)).'; ib=1:length(b);
a=a(:);
bsxfun(#(ii,jj) strcmp( a(ii),b(jj) ) ,ia, ib);
I'm afraid there's no such equivalent for cell-arrays :-(
As far as I can see, you can either:
Follow Oleg's suggestion and use loops
Use existing implementations such as mAryCellFcn or csxfun from the File Exchange.
Roll your own function. For example, here's a variant of Robert's idea that works for inputs of any dimensions (under the restrictions of bsxfun, of course) and an arbitrary binary function func:
function C = mybsxfun(func, A, B)
idx_A = reshape(1:numel(A), size(A));
idx_B = reshape(1:numel(B), size(B));
C = bsxfun(#(ii, jj)func(A(ii), B(jj)), idx_A, idx_B);
If your function can operate on entire cell arrays element-wise, you could perform a singleton expansion on your cell arrays first, and then feed them directly to the function func:
mask = bsxfun(#or, true(size(A)), true(size(B)));
idx_A = bsxfun(#times, mask, reshape(1:numel(A), size(A)));
idx_B = bsxfun(#times, mask, reshape(1:numel(B), size(B)));
C = func(A(idx_A), B(idx_B));
The latter method might be faster if func is optimized for vectorized operations on cell arrays.
How about
[str,ia,ib] = intersect(a,b)
?
As the error message says, broadcasting only works for numeric types. Here are other possible alternatives:
a = {'aa', 'bb', 'cc'};
b = {'dd'; 'aa'};
%# obviously doesnt work
%#bsxfun(#strcmp, a, b)
%# do the singleton expansion ourselves
strcmp(repmat(a,size(b)), repmat(b,size(a)))
%# if you dislike REPMAT, we can use Tony's trick
strcmp(a(ones(size(b)),:), b(:,ones(size(a))))
%# we could also use CELLFUN
cell2mat(cellfun(#(s)strcmp(a,s), b, 'UniformOutput',false))

Combining Anonymous Functions in MATLAB

I have a cell array of anonymous function handles, and would like to create one anonymous function that returns the vector containing the output of each function.
What I have:
ca = {#(X) f(X), #(X)g(X), ...}
What I want:
h = #(X) [ca{1}(X), ca{2}(X), ...]
Yet another way to it:
You can use cellfun to apply a function to each cell array element, which gives you a vector with the respective results. The trick is to apply a function that plugs some value into the function handle that is stored in the cell array.
ca = {#(X) X, #(X) X+1, #(X) X^2};
h=#(x) cellfun(#(y) y(x), ca);
gives
>> h(4)
ans =
4 5 16
You can use str2func to create your anonymous function without having to resort to eval:
ca = {#sin,#cos,#tan}
%# create a string, using sprintf for any number
%# of functions in ca
cc = str2func(['#(x)[',sprintf('ca{%i}(x) ',1:length(ca)),']'])
cc =
#(x)[ca{1}(x),ca{2}(x),ca{3}(x)]
cc(pi/4)
ans =
0.7071 0.7071 1.0000
I found that by naming each function, I could get them to fit into an array. I don't quite understand why this works, but it did.
f = ca{1};
g = ca{2};
h = #(X) [f(X), g(X)];
I feel like there should be an easier way to do this. Because I am dealing with an unknown number of functions, I had to use eval() to create the variables, which is a bad sign. On the other hand, calling the new function works like it is supposed to.

Matlab: how to create infinitly deep for-loops?

So we are given with some w and we want to so something like such pseudocode:
u = zeros(size(w));
for o=1:length(size(w))
for i=1:size(w)(1),
for j=1:size(w)(2),
...
for k=1:size(w)(length(size(w))),
u(i, j, ..., k )=1/(exp((-w(i,j, ..., k )))+25);
end
...
end
end
end
is such thing possible with Matlab and how to do it?
This is certainly possible, but also not recommended, since it's very non-idiomatic.
For simplicity, I assume that there is a typo in your question and that it should say exp(-w(i,j,...)).
Then, u can be calculated as
u = exp(-w);
You can use recursion - write a function, that iterates over the desired variables, and calls itself each time.
#Jonas's answer is the best option, however for a general-purpose code (one that #Jonas's 'matricized' answer does not apply), you can use a code-generation approach, for example:
fcode = fopen('manyForLoopsScript.m','w');
w = rand(2,3,4);
numLoops = length(size(w));
u = zeros(size(w));
% open the 'for' loops
for m = 1 : numLoops
fprintf(fcode, 'for a%d = 1:size(w,%d)\n',m,m);
end
% the actuall 'stuff'
indStr = [];
for m = 1 : numLoops
indStr = [indStr,sprintf('a%d,',m)];
end
indStr = indStr(1:end-1);
fprintf(fcode, ['u(' indStr ') = exp(-w(' indStr '));\n']);
% close the 'for' loops
for m = 1 : numLoops
fprintf(fcode, 'end\n');
end
fclose(fcode);
manyForLoopsScript
One option is to rewrite the function you want to apply to be vectorized, so that it is computed element-wise (the same way EXP built-in function works for scalar/vector/matrix input):
u = 1./(exp(-w)+25);
Otherwise, if you prefer a for-loop, all you need to do is to traverse the multi-dimensional input matrix using linear indices (in a column-major order), apply the function to each element, then RESHAPE the result back into the expected shape:
u = zeros(numel(w),1);
for i=1:numel(w)
u(i) = 1 ./ ( exp(-w(i)) + 25 );
end
u = reshape(u, size(w));
This is basically what the ARRAYFUN functions does for you:
u = arrayfun(#(x) 1./(exp(-x)+25), w);
In the chance that you also need access to the actual indices while looping over the elements of the matrix, you could always get them with IND2SUB (which converts linear indices to subscripts), or even generate all of them with functions like MESHGRID and NDGRID...