Converting a function to cellfun format in MATLAB - matlab

I had a matrix A(32x8) for which I wrote the following function
function x = y(A)
x=[A(:,1:2),isnan(A(:,3:5)),A(:,6:end)];
x(sum((x==1),2)>0,:) = [];
end
Now I have an Array B (100x1) where each cell contains the Matrix A(32x8) with different values, So how can I write a function as same as above for all the cell in the array in MATLAB.
I tried following way
Class=cellfun(#(x) x{:,1:2},isnan{x{:,3:5}},x{:,6:end},B, 'UniformOutput', false);

To apply your function y o each element in the cell array B, use cellfun as follows:
cellfun(#y, B, 'UniformOutput', false);
#y is a handle to the function you wrote. It must exist, so that if you write y(B{1}) you get the correct output for the first element in B. cellfun simply applies that function to all elements in the cell array. It is equivalent to writing a loop over B.

Related

Perform a function on each value of a vector in matlab?

I have a vector, a, shape (10000,1) filled with values. I also have vector b, same shape, filled with zeros. I want to take my function, apply it to each value in vector a, return those values into vector b. Below is what I tried, as well as a few variations of this. How can I perform this function on each value of the vector and replace each zero in vector b with what that function returns?
for i=1:length(a)
b(i) = function(a)
end
You can use arrayfun to do this
b = arrayfun(#someFunction, a); % Calls b(i) = someFunction(a(i)) for all elements of a
(Although it's common in MATLAB to try and make someFunction be "vectorised", so that you can instead say simple b = someFunction(a))

Apply a function to each sub-cell of a cell in Matlab?

I have a cell C in Matlab of dimension mx1, e.g. m=3
C={{1 2 3} {4 5 6} {7 8 9 10}}
Then I have a function g written in a separate m-file
function D=g(C{i},a,b)
...
end
that takes any sub-cell C{i} of C and using some other parameters a and b gives a vector D of dimension fx1.
I want to apply the function g to each sub-cell of C and assemble the obtained fx1 vectors in a matrix fxm without using loops. I have seen the command cellfun but I don't know how to make it working with a function written by myself. Any suggestion?
Simple. First make a handle to the function where the only input is the cell array:
h = #(x) D(x, a, b);
Here, x would be a cell from the cell array. Also, I'm going to assume that a and b are already defined in your workspace. After, just do this:
out = cellfun(h, C, 'uni', 0);
The first argument is a handle to the function, which we've already defined. The next parameter is the cell array you want to operate on and apply the function h to every cell in your array. You need to specify the uni=0 flag because the output is non-uniform. Because your function outputs a vector per cell, this is mandatory. If your function outputted a single value, then this declaration of uni=0 is not required.
Alternatively, you can do this in a loop... which is what cellfun ultimately performs:
out = cell(numel(C), 1);
for idx = 1 : numel(C)
out{idx} = D(C{idx}, a, b);
end
To me, the second option is more suitable for those who aren't used to using cellfun.

MATLAB: Simple cellfun does not work on string vector

I constructed my vector as such:
v = ['asdf'; 'qwer'; 'zxcv'];
I just wanted to take the first 2 characters, and I wrote a simple cellfun like so:
A = cellfun(#(x) x(1:2), v, 'UniformOutput', false);
However, it says:
error: cellfun: C must be a cell array
How should I extract the first 2 characters of each string?
That's because v is not a cell array. Turn it into one:
v = {'asdf'; 'qwer'; 'zxcv'};
If you can't use cell arrays, do what Divakar suggested and turn v into one by using cellstr:
v = ['asdf', 'qwer', 'zxcv'];
v_cell = cellstr(v);
If you want to escape the temporary variable, supply the call with v directly into cellfun:
A = cellfun(#(x) x(1:2), cellstr(v), 'UniformOutput', false);
If you want to un-cell the cell array, use cell2mat:
Aout = cell2mat(A);
I question the efficiency of the above though. If you just want to extract the first two characters of your cell array then turn it back into a character array, why don't you simply index the first two columns of all of the rows in the original character array? The use of cellfun adds unnecessary overhead when simple indexing would do the trick. Indexing is much more readable in this instance than using cellfun, which adds a layer of obfuscation.
Aout = v(:,1:2);

Converting Cell array of function handle into a single array of function handle

I need to build up a vector of non-linear equations to be used in fsolve to solve it. But I should make each element of the vector in each loop iteration. How can I make up such a vector? In fact, I can not use cell array. How can I convert a cell array like {#(x) x(1)+x(2)^2; #(x) x(1)-2*(x(2))} into an array like #(x) [ x(1)+x(2)^2 ; x(1)-2*(x(2))]? Because I want to use fsolve to solve the system of non-linear equations.
Use func2str to get the function definitions in string and use str2func to get the desired function, if A is the cell array containing the function handles:
B = strcat(regexprep(cellfun(#func2str, A, 'uni', 0), '^#\(x\)', ''), ';');
F = str2func(strcat('#(x) [', B{:}, ']'));
Now F contains the desired function handle.
Why convert? Why not use something like
% Your cell array
Fs = {#(x) x(1)+x(2)^2; #(x) x(1)-2*x(2)};
% Just use cellfun
solution = fsolve(#(y) cellfun(#(x) x(y), Fs), [0 0])

MATLAB: index a cell array with cell array of arrays and return a cell array

Say I have a cell array of (n X 1) vectors, A, and a cell array of vectors containing indices into A, called B. I wish to extract a cell array, C, such that C{i} = [A{B{i}}].
In other words, I have a cell array of arrays of indices, and I want to pull out the matrices corresponding to the concatenations of the vectors in A indexed by each of those arrays of indices.
for i = 1:length(B)
%# B{i} is an array of indices, C{i} is a matrix
C{i} = [ A{ B{i} } ];
end
The loop is equivalent to:
C = cellfun(#(x)[A{x}],B,'UniformOutput',false); %# implicit for loop w/ closure
Can I do that using an indexing expression alone? Or at least without the loop?
I think deal() might have to be involved but can't figure it out.
Here are two alternative solutions:
Collect all the indices of B together with the function cell2mat, index the contents of A to make one large matrix, then divide that matrix up using the function mat2cell and the sizes of the index arrays in B:
N = size(A{1}); % Size of an array in A
M = cellfun('prodofsize', B); % Array of sizes of elements in B
C = mat2cell([A{cell2mat(B)}], N, M);
Here's a more compact version of your cellfun-based solution:
C = cellfun(#(x) {[A{x}]}, B);
Ultimately, I would decide what solution to use based on speed and readability, which may actually turn out to be your for-loop-based solution.
Try the following expression:
C = A(cell2mat(B))
You may have a look at Loren's blog post about Cell Arrays and Their Contents