How to deal with error "Input #3 expected to be a cell array, was double instead." using cellfun?

Hello everyone,
as I'm trying to lean how to code with vectorization and do this magic with little lines and incredible performence there are a few hurdles for me to overcome. First I need to learn how to use cellfun correctly. Though I think the descriptions MathWorks gives are often usefull they are just examples and not always show me the solutions to my issues. Please note I am here to learn. There are a lot of things to learn for me. So I am thankful for ever advice to improve my coding. And I am not a native english speaker so there is the possibility that I just don't get right what the discription is supposed to tell me.
I have the following code:
[~,locs{1},~,~] = findpeaks(Mbx,t,'MinPeakHeight',maxPeakx,'MinPeakWidth',MinPeakWi,'MinPeakDistance', MinPeakDis ,'Annotate','extents');
[~,locs{2},~,~] = findpeaks(-Mbx,t,'MinPeakHeight',maxPeakx,'MinPeakWidth',MinPeakWi,'MinPeakDistance', MinPeakDis,'Annotate','extents');
[~,locs{3},~,~] = findpeaks(Mby,t,'MinPeakHeight',maxPeaky,'MinPeakWidth',MinPeakWi,'MinPeakDistance', MinPeakDis ,'Annotate','extents');
[~,locs{4},~,~] = findpeaks(-Mby,t,'MinPeakHeight',maxPeaky,'MinPeakWidth',MinPeakWi,'MinPeakDistance', MinPeakDis,'Annotate','extents');
In this case Mbx, Mby and t are arrays and the code works. It gives me the locations of the peaks in terms of t (time vector).
But I want to be able to get the same result in just one line without using a loop.
So I formed a cellarray with:
Mb = {Mbx -Mbx Mby -Mby};
and tried to perform a cellfun like this:
[~,locs,~,~] = cellfun(@(x)findpeaks(x,t,'MinPeakHeight',maxPeakx,'MinPeakWidth',MinPeakWi,'MinPeakDistance', MinPeakDis ,'Annotate','extents'),Mb,'UniformOutput',false);
I thought x is the input for my function and it performes findpeaks with all given name and value pairs on each cell of it.
But a get the error:
Error using cellfun
Input #3 expected to be a cell array, was double instead.
So what is Input #3 in this case? And how do I hand over the name value pairs for findpeaks correctly to the cellfun?
kind regards
Fabian

Answers (1)

Loops are not bad. cellfun is performing a loop.
Mb = {Mbx -Mbx Mby -Mby};
for k=1:4
[~,locs{k},~,~] = findpeaks(Mb{k},t,'MinPeakHeight',maxPeakx,'MinPeakWidth',MinPeakWi,'MinPeakDistance', MinPeakDis ,'Annotate','extents');
end

5 Comments

I don't say loops are bad. They just don't bring the performance I need. This is just a small subproblem out of my script that shows the problems I have with cellfun. There is far more than this to solve. I have loops so complex that the script needs up to over 2 mins to run a full cycle. I want the script with klassification, windowing and plotting time series with several millions of datapoint to run as fast as possible.
data_T2 = cell(length(apc2),4);
data_T2{length(apc2),4} = [];
for k = 1:4
if mod(k,2) == 0
q = 2;
else
q = 1;
end
for h = 1:find(cellfun('isempty',apc2(:,q2)),1)-1
data_T2{h,k} = apc2{h,k}(find(abs(tvc2{h,k}-firstloc{q}(h,1)) < 0.00001):end-find(abs(tvc2{h,k}-firstloc{q}(h,1)) < 0.00001));
data_T2{h,k}(:,2) = tvc2{h,k}(find(abs(tvc2{h,k}-firstloc{q}(h,1)) < 0.00001):end-find(abs(tvc2{h,k}-firstloc{q}(h,1)) < 0.00001));
end
end
figure(f11)
for p = 1:4
subplot(3,4,4+p)
hold all
for k1 = 1:sum(~cellfun(@isempty,apc2(:,q2)),1)
plot(data_T2{k1,p}(:,2)-data_T2{k1,p}(1,2), data_T2{k1,p}(:,1))
if p == 1
title('T2 Mbx positiv')
elseif p == 2
title('T2 Mbx negativ')
elseif p == 3
title('T2 Mby positiv')
elseif p == 4
title('T2 Mby negativ')
end
end
hold off
grid on
end
This is just a sneak peek but is takes just below 29 seconds to run. The script grew with time. I was never taught to code and try to learn it autodidactically. And as I wrote there is much to learn for me. But I thought let's go the whole hog and rebuild it from scatch.
Okay, I read comments from which I conclude the opposite. You are of the oppinion I should concentrade on writing better loops then?
"I read comments from which I conclude the opposite"
Please give a link to that MATLAB Answers thread.
"You are of the oppinion I should concentrade on writing better loops then?"
No, I am of the opinion that every tool has its uses.
"as I'm trying to lean how to code with vectorization and do this magic with little lines and incredible performence there are a few hurdles for me to overcome. First I need to learn how to use cellfun correctly."
CELLFUN is not really relevant to code vectorization. Read the definition here:
Okay sorry I believe you. I am barely six weeks into MATLAB and think I got something a little wrong and confused vectorisation with those one-liners where you call an anonymous function. It is kind of hard to understand all the descriptions with all those specific foreign words memorize and implement them.
But do you have any advice on how to write clearer loops and avoid things that slow down the performance? I thing those calls on find in a loop are sure a bad idea for the performance. But I simply did the work with the tools I know.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Release

R2021a

Asked:

on 25 Jun 2021

Commented:

on 25 Jun 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!