c=complex(a,b)
在Matlab中比在c=a+1i*b
中慢得多。
以下是Matlab 2018a中的
a=rand(15000);
b=rand(15000);
%
clear c;
tic; c=a+1i*b; toc
Elapsed time is 0.338525 seconds
%
clear c;
tic; c=complex(a,b); toc
Elapsed time is 2.542403 seconds.
在任何情况下,complex
真的有用吗?为什么这么慢?
答案 0 :(得分:5)
我想添加一些历史观点:
在R2018a之前的MATLAB版本中,复数在内部存储在单独的实数和虚数数组中。因此,complex
的结果只能指向两个输入数组的数据。因此,complex(a,b)
与实际上需要进行算术并创建新的存储器存储的a+1i*b
相比非常快且内存效率高。
在当前版本的MATLAB中,复杂数据以“交错格式”存储,这意味着它是一个单个数组,每个数组元素的实际值和复杂值彼此相邻。这意味着数据需要使用任何一种格式进行复制,complex
的值已丢失。
答案 1 :(得分:4)
documentation和命令行帮助在有用时提供了一些提示:当您想要强制复杂类型的结果,即使虚部为零时,或将整数数据类型作为输入时:
C = COMPLEX(A,B)
返回复杂结果A + Bi
如果
B
全为零,则C
的虚部全为零,这与加法A+0i
的结果严格返回实数不同。>在
complex
和A+1i*B
不是单或双的情况下,A+1j*B
函数可以有效替代A
或B
之类的表达式,或者B
全部为零时。
关于为什么它变慢:我们只能猜测,因为它是内置函数;但是检查输入是否不是浮点数或第二个输入是否为全零可能会占用一些额外时间。
答案 2 :(得分:2)
为什么这么慢?
不是,真的。但是您的“基准代码”不合适,因为每次运行或更改顺序时,其行为可能会有所不同。
timeit
函数是基准测试的专用函数。
function [t] = bench()
A = rand(10000);
B = rand(10000);
% functions to compare
fcns = {
@() compare1(A,B);
@() compare2(A,B);
};
% timeit
t = zeros(2,1);
for ii = 1:10
t = t + cellfun(@timeit, fcns);
end
end
function c = compare1(a,b)
c = a + 1i*b;
end
function c = compare2(a,b)
c = complex(a,b);
end
十次运行会导致:
8.0663 % a + 1i*b
8.3191 % complex(a,b)
如您所见,没有太大区别。如Luis Mendo所述,其中一个可以解决complex
(类型检查,强制转换)的功能开销。
除了Luis Mendo's answer之外,还有其他原因可能导致此功能存在:
[1,2,3]+1i*[1;2;3]
相同的bsxfun(@(x,y) x+1i*y, [1,2,3], [1;2;3])
,但是这个bsxfun(@complex, [1,2,3], [1;2;3])
可能比第二个选项要快(对于cellfun和arrayfun同样适用,尽管我可以这样做)进行测试。)complex
而不支持a+1i*b
的Matlab代码中自动生成C代码。有许多工业应用程序都严重依赖此功能。