# Matlab:matlab中的arrayfun函数
最近了解matlab中存在arrayfun这种类型的函数,帮助手册中有说明该函数的基本用法,现在对该函数进行效率测试
clc;
A=rand(2000,2000);
func=@(x) exp(x)*x+cos(x)*sin(x)^2;
func2=@(x) exp(x).*x+cos(x).*sin(x).^2;
%%% Method 1: arrayfun 函数
fprintf("Method 1:");
tic
A1=arrayfun(func,A);
toc
%%% Method 2:多层 for 循环
fprintf("Method 2:");
tic
A2=A;
for i=1:1:size(A,1)
for j=1:1:size(A,2)
A2(i,j)=func(A(i,j));
end
end
toc
fprintf("Method 3:");
%%% Method 3:矩阵运算
tic
A3=func2(A);
toc
输出
Method 1:历时 7.390905 秒。
Method 2:历时 0.324508 秒。
Method 3:历时 0.023560 秒。
可以发现arrayfun函数效率明显降低,
https://ww2.mathworks.cn/matlabcentral/answers/324130-is-arrayfun-faster-much-more-than-for-loop
mathworks论坛中也存在arrayfun效率相关问题的讨论。
总结
- arrayfun函数可以视作matlab编程语言上的一种语法糖,可以简化多层for循环代码编写。
- 但是经过实际测试,运用该函数会降低运行效率,而且不适合应用parfor等并行方法对其进行计算加速。
- 如果需要利用matlab进行编程,将数值计算转化成为矩阵运算的形式(如Method 3)具有最高的计算效率。
- 另外:arrayfun帮助文档中说明可以使用GPU Parallel Box,可能会有内部黑魔法加持,或许可以一试。
bsxfun函数
A = rand(4000,4000);
B = rand(4000,4000);
func3=@(a,b) a*exp(b)*cos(a)*sin(b);
func4=@(a,b) a.*exp(b).*cos(a).*sin(b);
%%% Method 1: bsxfun 函数
fprintf("bsxfun :");
tic
C = bsxfun(func3, A, B);
toc
%%% Method 2:多层 for 循环
fprintf("For loop:");
tic
A2=A;
for i=1:1:size(A,1)
for j=1:1:size(A,2)
A2(i,j)=func3(A(i,j),B(i,j));
end
end
toc
%%% Method 3:矩阵运算
fprintf("Matrix:");
tic
A3=func4(A,B);
toc
输出
bsxfun :历时 1.906500 秒。
For loop:历时 2.285549 秒。
Matrix:历时 0.065219 秒。
bsxfun函数优于for循环