How to use arrayfun with built-in Matlab functions where the variable parameter is passed with 'Name', 'Value'?
    5 ビュー (過去 30 日間)
  
       古いコメントを表示
    
I want to speed up a for loop where I call the function findpeaks, hence I thought of using arrayfun.
What I want to change in each loop iteration is the value of the 'MinPeakHeight' argument in findpeaks. 
   x=[ 6.9100    6.1800    6.0500    5.7900    5.5000    5.2400    4.9800    4.6800    4.5100    4.6191    5.2582    5.9801    6.9525   13.2387   13.5548   12.1637   10.3495    9.2243...
    9.0334    6.3900    6.3300    6.0500    6.1700    6.1100    6.0800    5.0500    5.4400    6.2600    6.5400    6.7100    6.8000    6.8700    7.1000    7.3533    8.1032    9.0265...
    9.7520   13.5191   12.7585   11.8784   10.5339    9.6431    9.0825    5.8300    5.5700    5.3700    5.3300    5.2900    5.2500    4.7900    4.6700    4.6300    4.6100    4.4800...
    4.3600    4.4600    4.3600    4.5097    5.3665    6.5823    7.9431   16.3444   15.5453   13.4917   11.2298    9.7031    8.6474    3.6500    3.5400    3.4900    3.4900    3.4800...
    3.4700    3.0600    3.0200    2.9500    2.9100    2.8700    2.8400    2.4900    2.5200    3.2049    5.3079    7.6541    9.6458   18.2013   16.7009   14.3508   11.7695   10.0188...
    8.7262    2.7400    2.6100    2.4400    2.1700    1.9200    1.6900    1.8600    1.6400    1.4400];
a.MPH=[8;10;12;14;16];
A = arrayfun(@(Y) findpeaks(x,'MinPeakHeight',Y.MPH) ,a ) ;
But I get error message saying that MinPeakHeight has to be a scalar:

The problem is that it is precisely MinPeakHeight what I want to change to avoid the for loop...
I might be commiting some syntaxis errors, I tried different things, but I cannot make it work.
Is there a way out of it, or should I stick with the for loop?
2 件のコメント
  Stephen23
      
      
 2025 年 7 月 1 日
				"I want to speed up a for loop where I call the function findpeaks, hence I thought of using arrayfun."
A well-written FOR-loop is likely to be faster than ARRAYFUN.
採用された回答
  Torsten
      
      
 2025 年 7 月 1 日
           x=[ 6.9100    6.1800    6.0500    5.7900    5.5000    5.2400    4.9800    4.6800    4.5100    4.6191    5.2582    5.9801    6.9525   13.2387   13.5548   12.1637   10.3495    9.2243...
    9.0334    6.3900    6.3300    6.0500    6.1700    6.1100    6.0800    5.0500    5.4400    6.2600    6.5400    6.7100    6.8000    6.8700    7.1000    7.3533    8.1032    9.0265...
    9.7520   13.5191   12.7585   11.8784   10.5339    9.6431    9.0825    5.8300    5.5700    5.3700    5.3300    5.2900    5.2500    4.7900    4.6700    4.6300    4.6100    4.4800...
    4.3600    4.4600    4.3600    4.5097    5.3665    6.5823    7.9431   16.3444   15.5453   13.4917   11.2298    9.7031    8.6474    3.6500    3.5400    3.4900    3.4900    3.4800...
    3.4700    3.0600    3.0200    2.9500    2.9100    2.8700    2.8400    2.4900    2.5200    3.2049    5.3079    7.6541    9.6458   18.2013   16.7009   14.3508   11.7695   10.0188...
    8.7262    2.7400    2.6100    2.4400    2.1700    1.9200    1.6900    1.8600    1.6400    1.4400];
a.MPH=[8;10;12;14;16];
A = arrayfun(@(Y) findpeaks(x,'MinPeakHeight',Y) ,a.MPH,'UniformOutput',0 ) 
その他の回答 (1 件)
  John D'Errico
      
      
 2025 年 7 月 1 日
        
      編集済み: John D'Errico
      
      
 2025 年 7 月 1 日
  
      I see this soooo often, people thinking arrayfun is a good way to speed up code. But, is it, really? Arrayfun is a nice tool to apply an implicit loop.
For example...
Mn = @(n) sym(2).^n - 1;
n = primes(750);
timeit(@() arrayfun(@isprime,Mn(n)))
ans =
9.307847450625
timeit(@() isprime(Mn(n)))
ans =
9.368681450625
But, could I have just used a simple loop? Trivially, yes.
tic,for i = 1:numel(n),isprime(Mn(n(i)));end,toc
Elapsed time is 9.406175 seconds.
The loop overhead is quite small, at least compared to the operations internally.
Again, arrayfun just replaces an explicit loop, say a for or a while loop, with an implicit loop, where that loop is generated internally. Did we gain much? NO. And it will be very rare indeed where a tool like arrayfun can give you a significant improvement in processing speed. Arrayfun and cellfun are great tools, don't get me wrong. They can clean up your code, maybe a tiny boost in speed, SOMETIMES.
But if you are spending a lot of effort to gain a 1% improvement in processing time, then you may want to recosnsider where you are investing your programming efforts.
Why then, why do you use a tool like arrayfun? Often, it is a matter of convenience. They allow you to apply a function to an array, then collecting the results in one place very conveniently. For example
N = (2:20)';
Flist = arrayfun(@factor,N,uniformoutput = false)
Flist =
  19×1 cell array
    {[      2]}
    {[      3]}
    {[    2 2]}
    {[      5]}
    {[    2 3]}
    {[      7]}
    {[  2 2 2]}
    {[    3 3]}
    {[    2 5]}
    {[     11]}
    {[  2 2 3]}
    {[     13]}
    {[    2 7]}
    {[    3 5]}
    {[2 2 2 2]}
    {[     17]}
    {[  2 3 3]}
    {[     19]}
    {[  2 2 5]}
As you can see, it is a very nice, slick way to collect the results of something, where the results will vary in size. And I can apply cellfun to that result now too.
UniqFacs = cellfun(@unique,Flist,'UniformOutput',false)
UniqFacs =
    19×1 cell array
    {[  2]}
    {[  3]}
    {[  2]}
    {[  5]}
    {[2 3]}
    {[  7]}
    {[  2]}
    {[  3]}
    {[2 5]}
    {[ 11]}
    {[2 3]}
    {[ 13]}
    {[2 7]}
    {[3 5]}
    {[  2]}
    {[ 17]}
    {[2 3]}
    {[ 19]}
    {[2 5]}
Again, a nice, clean way to solve a problem. The loops are implicit, so only generated internally. But don't waste sleep on whether those calls saved any CPU time! The only time saved was my own, since it took fewer lines of code to write them. But a for loop is a pretty simple thing to write.
1 件のコメント
  Steven Lord
    
      
 2025 年 7 月 1 日
				One of the use cases for arrayfun is in places where you can't put an explicit loop, specifically inside an anonymous function.
IIRC both arrayfun and structfun were introduced at the same time we enhanced cellfun to accept an arbitrary function handle rather than one of a small fixed list of "things to compute", for parity between cell arrays and other types of arrays in terms of "do something to each element" (or in the case of structfun, "each field") of the data input. For backwards compatibility (as explicitly stated on the cellfun documentation page) cellfun still accepts that "small fixed list" as the func input, but you'll note that neither arrayfun nor structfun do.
C = {1, 2:3, [4 5; 6 7]}
X1 = cellfun('prodofsize', C) % One of the "small fixed list"
X2 = cellfun(@numel, C) % Function handle version
S = struct('x1', 1, 'x2', [2 3], 'x3', [4 5; 6 7])
Y1 = structfun(@numel, S) % Allowed
Y2 = structfun('prodofsize', S) % Not allowed
参考
カテゴリ
				Help Center および File Exchange で Loops and Conditional Statements についてさらに検索
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




