Well, simply define a new anonymous function as @(x) myFunc(x,4) and use it this way:
F = cellfun(@(x) myFunc(x,4), C)
Answer from knedlsepp on Stack OverflowIs there a better way to use cellfun with arguments? and is it better than for-loop?
cellfun for function with multiple inputs
matlab - How to apply cellfun (or arrayfun or structfun) with constant extra input arguments? - Stack Overflow
can i used cellfun with a function which has more than one input?
You can do this using an anonymous function that calls myfun with the two additional arguments:
cellfun(@(x) myfun(x,const1,const2), cellarray)
Another trick is to use ARRAYFUN on the indices:
arrayfun(@(k) myfun(cellarray{k},const1,const2), 1:numel(cellarray))
if the return values of myfun are not scalars, you might want to set the 'UniformOutput',false option.
Hiya,
I'm trying to specifically use cellfun to use the function extractFeatures on multiple detected points from a SURF detection in the computer vision toolbox. The problem I'm having is that the inputs are both cell arrays which doesn't allow me to put one of them as the cell array. Should add I'm trying to extract features for 118 images.
Here is what I've tried:
g = cellfun(@rgb2gray,images,'UniformOutput',false); points = cellfun(@detectSURFFeatures,g,'UniformOutput',false); [features, valid_points] = cellfun(@(x) extractFeatures(G, points), g);
Where g & points are cell arrays with size 1x118.
Any help is much appreciated.
To do this very fast, do not use either cellfun or str2double. Some possibilities:
strjoin with sscanf
Use strjoin to combine the strings in cell array x into a single long space-delimited string, which can then be parsed very quickly with sscanf:
sscanf(strjoin(reshape(x,1,[])),'%f')
Note the reshape is included to guarantee the cell array is a row, as required by strjoin. A simple permute (.') could be used if you know x is a column, or nothing if x is already a row.
vertcat (or str2mat) with sscanf
Instead of strjoin, form a virtual comma-separated list of strings with x{:} and vertically concatenate them with vertcat (if each string has the same number of characters). Transpose this 2D character array and sscanf can again parse it quickly in a single shot:
sscanf(vertcat(x{:})','%f');
Or if the number of characters varies from string to string, you can use str2mat, which creates a space-padded 2D character array that sscanf also happily reads:
sscanf(str2mat(x)','%f');
test
Create a cell array of string representations of 10,000 random numbers:
>> x = sprintfc('%f',rand(1e4,1));
Note the use of the undocumented sprintfc to print to cells.
Reference methods:
>> tic; d0 = str2double(x); toc
Elapsed time is 0.302148 seconds.
>> tic; d1 = cellfun(@(x) sscanf(x,'%f'),x); toc
Elapsed time is 0.277386 seconds.
>> isequal(d0,d1)
ans =
1
strjoin and vertcat:
>> tic; d2 = sscanf(strjoin(reshape(x,1,[])),'%f'); toc
Elapsed time is 0.068129 seconds.
>> isequal(d0,d2)
ans =
1
>> tic; d3 = sscanf(vertcat(x{:}).','%f'); toc
Elapsed time is 0.024312 seconds.
>> isequal(d0,d3)
ans =
1
>> tic; d4 = sscanf(str2mat(x).','%f'); toc
Elapsed time is 0.011917 seconds.
>> isequal(d0,d4)
ans =
1
Note: these numbers are ballpark as then should be run over multiple iterations inside of a script or function, but all code is warmed. Try them out.
How about a wrapper for the sscanf?
myWrapper = @(x) sscanf(x, '%f')
x={'0.17106'; '2.11462'; '4.13938'; '6.24203'}
cellfun(myWrapper,x)
str2double(x)