Matlab中级数求和的性能分析

Matlab中级数求和的性能分析,matlab,time,sum,Matlab,Time,Sum,我正在写一个Matlab程序,通过级数求和来计算pi A = Sum of a_i from i=1 to N 在哪里 pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 ... 要通过级数求和计算pi,建议的方法是 a_i = (-1)^(i+1)/(2i-1) 为了做到这一点,我写了下面的程序 n=100; f=[]; for jj=1:n ii=1:jj; f=[f 4*sum( ((-1).^(ii+1))./(2.*ii-

我正在写一个Matlab程序,通过级数求和来计算pi

A = Sum of a_i from i=1 to N
在哪里

pi/4 = 1 - 1/3 + 1/5 - 1/7 + 1/9 - 1/11 + 1/13 ...
要通过级数求和计算pi,建议的方法是

a_i = (-1)^(i+1)/(2i-1)
为了做到这一点,我写了下面的程序

n=100;
f=[];
for jj=1:n
    ii=1:jj;
    f=[f 4*sum( ((-1).^(ii+1))./(2.*ii-1)  )];
end;
hold on
plot(f)
title('Computing of \pi using a finite sum')
xlabel('Number of summations') 
ylabel('Estimated value of \pi') 
plot(1:size(f,2),ones(size(f))*pi)
该程序表明,级数近似在N=80附近有一定的精度

我现在正试图调整我的程序,以便y轴显示总计算时间T_N,x轴显示总和的数量N。总计算时间T_N应随着N的增加而增加。理想情况下,我希望图形显示接近TN和N之间的线性关系

为了做到这一点,我调整了我原来的计划如下

n=100;
f=[];
tic
for jj=1:n
    ii=1:jj;
    f=[f 4*sum( ((-1).^(ii+1))./(2.*ii-1)  )];
end;
hold on
plot(f)
title('Time it takes to sum \pi using N summations')
xlabel('Number of summations (N)') 
ylabel('Total Time (T_N)') 
plot(1:size(f,2),toc)
slope = polyfit(1:size(f,2),toc,1);
这看起来不对。我一定是错误地应用了Matlab tic和toc中的内置定时函数。因此,我将分析我的代码并提出两个问题-

如何调整上述代码,使y轴正确显示每次求和N的总计算时间?看起来我在图1中做错了什么:sizef,2,toc

在获得y轴以显示正确的总计算时间T_N后,我应该能够使用polyfit命令来查找TN/N的斜率。这将给出TN和N之间的线性关系。然后我可以使用斜率=polyfit1:sizef,2,toc,1的值来计算

t_N=a+b*N

其中,t_N是为N的每个值计算的,b是通过polyfit命令计算的斜率


我认为在正确显示y轴并正确引用polyfit命令后,我应该能够找到a和b的值。

如果我正确理解您的问题,我认为这里有两个不同的问题。首先,绘制结果函数,然后绘制比pi小几个数量级的经过时间:

 hold on
 plot(f)  % <---- Comment me out!
 ...stuff...
 plot(1:size(f,2),toc)

请注意执行时间斜率的新多边形拟合表达式。这有帮助吗?

如果我正确理解您的问题,我认为这里有两个不同的问题。首先,绘制结果函数,然后绘制比pi小几个数量级的经过时间:

 hold on
 plot(f)  % <---- Comment me out!
 ...stuff...
 plot(1:size(f,2),toc)

请注意执行时间斜率的新多边形拟合表达式。这有帮助吗?

代码中有几点可以改进:

f应该预先分配,以免浪费时间重复分配内存。 应在循环内调用tic,以便重新启动秒表计时器。 当你打电话给toc时,你会得到上次tic的当前时间。所花费的时间应该存储在一个向量中,该向量也是预先分配的。 由于你想要计算的时间非常快,测量它们所花费的时间是非常不可靠的。计算应该重复很多次,因此测量的时间更大,精度也更好。更好的方法是使用如下所示。 不能在同一个图形中绘制时间和结果,因为比例差异太大。 包含这些变更的代码是:

n = 100;
f = NaN(1,n); % preallocate
times = NaN(1,n); % preallocate
repeat_factor = 1e4; % repeat computations for better time accuracy
for jj=1:n
    tic % initiallize time count
    for repeat = 1:repeat_factor % repeat many times for better time accuracy
        ii=1:jj;
        f(jj) = 4*sum( ((-1).^(ii+1))./(2.*ii-1) ); % store value
    end
    times(jj) = toc; % store time
end
times = times / repeat_factor; % divide by repeat factor
plot(f)
title('Time it takes to sum \pi using N summations')
xlabel('Number of summations (N)') 
ylabel('Total Time (T_N)')
figure % new figure for time
plot(1:size(f,2), times)
p = polyfit(1:size(f,2),times,1);
slope = p(1);
用于测量时间可能会提高精度,但不是很好,因为如上所述,要计算时间的计算速度非常快。要使用timeit,您需要使用要计时的代码定义一个函数。最简单的方法是使用不带输入参数的。请参阅下面的代码

n = 100;
f = NaN(1,n); % preallocate
times = NaN(1,n); % preallocate
for jj=1:n
    ii=1:jj;
    fun = @() 4*sum( ((-1).^(ii+1))./(2.*ii-1) );
    f(jj) = fun(); % store value
    times(jj) = timeit(fun); % measure and store time
end
plot(f)
title('Time it takes to sum \pi using N summations')
xlabel('Number of summations (N)') 
ylabel('Total Time (T_N)')
figure % new figure for time
plot(1:size(f,2), times)
p = polyfit(1:size(f,2),times,1);
slope = p(1);

您的代码中有几个地方可以改进:

f应该预先分配,以免浪费时间重复分配内存。 应在循环内调用tic,以便重新启动秒表计时器。 当你打电话给toc时,你会得到上次tic的当前时间。所花费的时间应该存储在一个向量中,该向量也是预先分配的。 由于你想要计算的时间非常快,测量它们所花费的时间是非常不可靠的。计算应该重复很多次,因此测量的时间更大,精度也更好。更好的方法是使用如下所示。 不能在同一个图形中绘制时间和结果,因为比例差异太大。 包含这些变更的代码是:

n = 100;
f = NaN(1,n); % preallocate
times = NaN(1,n); % preallocate
repeat_factor = 1e4; % repeat computations for better time accuracy
for jj=1:n
    tic % initiallize time count
    for repeat = 1:repeat_factor % repeat many times for better time accuracy
        ii=1:jj;
        f(jj) = 4*sum( ((-1).^(ii+1))./(2.*ii-1) ); % store value
    end
    times(jj) = toc; % store time
end
times = times / repeat_factor; % divide by repeat factor
plot(f)
title('Time it takes to sum \pi using N summations')
xlabel('Number of summations (N)') 
ylabel('Total Time (T_N)')
figure % new figure for time
plot(1:size(f,2), times)
p = polyfit(1:size(f,2),times,1);
slope = p(1);
用于测量时间可能会提高精度,但不是很好,因为如上所述,要计算时间的计算速度非常快。要使用timeit,您需要使用要计时的代码定义一个函数。最简单的方法是使用不带输入参数的。请参阅下面的代码

n = 100;
f = NaN(1,n); % preallocate
times = NaN(1,n); % preallocate
for jj=1:n
    ii=1:jj;
    fun = @() 4*sum( ((-1).^(ii+1))./(2.*ii-1) );
    f(jj) = fun(); % store value
    times(jj) = timeit(fun); % measure and store time
end
plot(f)
title('Time it takes to sum \pi using N summations')
xlabel('Number of summations (N)') 
ylabel('Total Time (T_N)')
figure % new figure for time
plot(1:size(f,2), times)
p = polyfit(1:size(f,2),times,1);
slope = p(1);

是的,我明白我的错误。我需要将toc存储在for循环中,您已经将其作为telapsedjj=toc;。我可以将最后一行代码调整为以下值,以找到斜率和y截距。p=polyfit1:n,telapsed,1;斜率=p1%t_N=a+b*N的斜率,或是bintercept=p2%y截距或是,我看到了我的错误。我需要将toc存储在for循环中,您已经将其作为telapsedjj=toc;。我可以将最后一行代码调整为以下值,以找到斜率和y截距。p=polyfit1:n,telapsed,1;斜率=p1%t_N=a+b*N的斜率,或bintercept=p2%y截距或aOne也可以计算
e通过截距的y截距=p2。重复因子会导致大N>1000的运行时间较长。是否绝对有必要优化代码以将重复系数设置为1e4?我发现一个解决方法是应用timeit。如果需要,重复因子可以减少。其目的只是增加运行时间,以便更容易测量。还可以通过intercept=p2计算y-截距。重复因子导致N>1000时的运行时间较大。是否绝对有必要优化代码以将重复系数设置为1e4?我发现一个解决方法是应用timeit。如果需要,重复因子可以减少。它的目的只是增加运行时间,以便更容易测量