Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 矩阵元素求和的最快方法_Matlab_Sum_Processing Efficiency_Memory Efficient_Space Efficiency - Fatal编程技术网

Matlab 矩阵元素求和的最快方法

Matlab 矩阵元素求和的最快方法,matlab,sum,processing-efficiency,memory-efficient,space-efficiency,Matlab,Sum,Processing Efficiency,Memory Efficient,Space Efficiency,我的代码的效率有一些问题。基本上,我的代码是这样工作的: a = zeros(1,50000); for n = 1:50000 a(n) = 10.*n - 5; end sum(a); 求解此矩阵所有元素之和的最快方法是什么?首先,要通过向量乘法删除for循环: tic a = zeros(1,50000); b = [1:50000]; a = 10.*b-5; result = sum(a); toc Elapsed time is 0.008504 seconds.

我的代码的效率有一些问题。基本上,我的代码是这样工作的:

a = zeros(1,50000);
for n = 1:50000
    a(n) = 10.*n - 5;
end
sum(a);

求解此矩阵所有元素之和的最快方法是什么?

首先,要通过向量乘法删除for循环:

tic
a = zeros(1,50000);
b = [1:50000];
   a = 10.*b-5;
result = sum(a);
toc
Elapsed time is 0.008504 seconds.
另一种方法是简化操作,将1到50000乘以10,再减去5,然后求和(这是一个数字),这相当于:

tic
result = sum(1:50000)*10 - 5*50000;
toc
Elapsed time is 0.003851 seconds.
或者,如果你真的喜欢数学(这是一种纯数学表达式方法):

正如你所看到的,一点数学比纯粹的高效编程更有用,实际上,循环并不总是慢的,在你的例子中,循环实际上比矢量化方法快:

tic
a = zeros(1,50000);
  for n = 1:50000
     a(n)=10.*n-5;
  end
sum(a);
toc
Elapsed time is 0.006431 seconds.

时机 让我们做一些计时,看看结果。底部提供了自己运行它的功能。近似执行时间
execTime
以秒为单位,改进百分比
impPercentage
以%为单位

结果
  • OSX 10.11.4上的R2016a

                   execTime     impPercentage
                  __________    _____________
    loop          0.00059336         0       
    vectorized    0.00014494    75.574       
    adiel         0.00010468    82.359       
    math          9.3659e-08    99.984       
    
代码 以下函数可用于生成输出。请注意,至少需要R2013b才能使用内置的
timeit
-功能和

function timings
%feature('accel','on')      %// commented out because it's undocumented
cycleCount = 100;
execTime = zeros(4,cycleCount);
names = {'loop';'vectorized';'adiel';'math'};
w = warning;
warning('off','MATLAB:timeit:HighOverhead');
for k = 1:cycleCount
    execTime(1,k) = timeit(@()loop,1);
    execTime(2,k) = timeit(@()vectorized,1);
    execTime(3,k) = timeit(@()adiel,1);
    execTime(4,k) = timeit(@()math,1);
end
warning(w);
execTime = min(execTime,[],2);
impPercentage = (1 - execTime/max(execTime)) * 100;
table(execTime,impPercentage,'RowNames',names)


function result = loop
a = zeros(1,50000);
for n = 1:50000
    a(n) = 10.*n - 5;
end
result = sum(a);

function result = vectorized
b = 1:50000;
a = 10.*b - 5;
result = sum(a);

function result = adiel
result = sum(1:50000)*10 - 5*50000;

function result = math
result = (1+50000)*(50000/2)*10 - 5*50000;

这段代码的性能问题是什么?据我所知,没有比求和更快的方法了。但是,您可以像这样更容易地生成
a
-矩阵:
n=1:50000;a=10*n-5(1)oops。我的错。刚刚编辑了这篇文章。(2) 我只是想知道是否有更快的方法来计算总和。:)这些计时不具有代表性,因为您只执行了一次。做10'000次或更多次,才能看到矢量化的解决方案快3倍以上。为什么所有这些。。。?简单的
a=10*(1:50000)-5
比任何选项都快得多。@Matt不,我得到了类似的性能结果,你想分享你的代码/答案以便我尝试重新创建吗?@Matt这个问题已编辑到社区wiki,也许其他人可以解释/编辑我们得到的不同结果。谢谢你添加了计时性能@Matt,我在测试这个时有2010b版本。
function timings
%feature('accel','on')      %// commented out because it's undocumented
cycleCount = 100;
execTime = zeros(4,cycleCount);
names = {'loop';'vectorized';'adiel';'math'};
w = warning;
warning('off','MATLAB:timeit:HighOverhead');
for k = 1:cycleCount
    execTime(1,k) = timeit(@()loop,1);
    execTime(2,k) = timeit(@()vectorized,1);
    execTime(3,k) = timeit(@()adiel,1);
    execTime(4,k) = timeit(@()math,1);
end
warning(w);
execTime = min(execTime,[],2);
impPercentage = (1 - execTime/max(execTime)) * 100;
table(execTime,impPercentage,'RowNames',names)


function result = loop
a = zeros(1,50000);
for n = 1:50000
    a(n) = 10.*n - 5;
end
result = sum(a);

function result = vectorized
b = 1:50000;
a = 10.*b - 5;
result = sum(a);

function result = adiel
result = sum(1:50000)*10 - 5*50000;

function result = math
result = (1+50000)*(50000/2)*10 - 5*50000;