function [cosValue,realcos,real_N] = mycos(x,N) %mycos 通过N阶泰勒级数计算给定点x处的cos(x)。 % x 具体的x值 % N 泰勒级数的阶数 经验证(具体见下面mycosN函数) % 将cosx x值转入0-2*pi内计算,取N=11 即可。 % cosValue 函数mycos的输出值 % real_N 满足精确度 10^(-4)下,真正需要的泰勒项数,用于检验, %若出现 real_N>11,则本论述出错。算法错误 k=1:N; a_k=double((-1).^k.*x.^(2*k)./factorial(2*k)); %泰勒级数每一项/factorial阶乘函数 cosValue=1+sum(a_k);%求和函数 realcos=cos(x); while(abs(cosValue-realcos)>=0.001) N=N+1; a_k1=double((-1).^N.*x.^(2*N)./factorial(2*N)); cosValue=cosValue+a_k1; end real_N=N; end
验证“cosx x值转入0-2*pi内计算,取N=11 即可。”
计算0-2*pi的cosx值,当精确度度要求为10的-4次方
考虑到cosx的周期性,计算时,x可以转换到0-2pi内计算,故改变 X的取样间隔。
泰勒级数展开的截断误差
(-1).^N.x.^(2N)./(2*N)的阶乘 考虑展开式中的每一项,
当N值越大,分母上的x的2n次方幂次讲远远大于分母上的阶乘项.
自然若是取N趋向于无穷,可解出cosx的准确值;但我们计算时候,必定涉及到截断(有限项)
问题:
1.是否是x取值越大,泰勒级数展开项要求越多?
2.到底N到多少停止,才会避免截断误差(可能最后几项使得整体计算偏移量巨大)?
检测有:
1.
X=0:0.0001:2pi; (real_max)Nmax=11
X=0:0.00001:2pi)(real_max)Nmax=11
2.当带入 mycos(x,N)(x=0:0.0001:2pi;N=11时)
计算上述两个x的离散点集合时候, 都成功计算出了满足精确度要求的cos值
3.plot(x,N)(x=0:0.0001:2pi,N=11)
画出图像,图像同cosx的图像(见后附图)
所以,根据以上两点,这个问题,我们将之浓缩在0-2*PI区间内便不需考虑,取N=11时
% 认为满足cos值的计算
plot(x,cosValue,'-x','MarkerIndices',1:1:length(cosValue));
%每隔一点显示一个交叉标记,用实线连接
>> xlabel('x=0:0.001:2*pi');
>> ylabel('cosx 值');
>> print('-dpng','-r100','pic1')
% 输出png照片 -r 设置图像分辨率(dpi) 默认图片大小 8inx6in
function [cosValue,realcos,real_NmaxN,real_max] = mycosN(X,N) %mycos 通过N阶泰勒级数计算给多个定点处的cos(x)。并计算实际满足精确度时,在给定输入定点下(可能这些定点取不到最多展开项),所需要展开的最多项数目 % X 多个定点的数组集合 % N 泰勒级数的阶数 % cosValue: N项泰勒计算下,定点的cos值(数组) % realcos: matlab内置cos函数的cos值(数组) % real_NmaxN:满足10的-4次方精确度下,对于各点所真实需要的泰勒展开项数 % real_max: real_NmaxN的最大值,即满足10的-4次方精确度下,泰勒展开的一般需要项数 real_Nmax=0; cosValue=zeros(1,length(X)); realcos=zeros(1,length(X)); real_NmaxN=zeros(1,length(X)); i=0; for j=X %j将遍历数组X i=i+1; k=1:N; a_k=double((-1).^k.*j.^(2*k)./factorial(2*k)); cosValue(i)=1+sum(a_k); realcos(i)=cos(j); cos_compare=cosValue(i); while(abs(cos_compare-realcos(i))>=0.0001) N=N+1; a_k1=double((-1).^N.*j.^(2*N)./factorial(2*N)); cos_compare=cos_compare+a_k1; end real_N=N; if(real_N>real_Nmax) real_Nmax=real_N; end real_NmaxN(i)=real_Nmax; end real_max=max(real_NmaxN); end
从本质来讲,数学符号是一种通用语言,它能应用到包括matlab在内的任何编程语言。
Programming with MATLAB for Scientists, A Beginner's Introduc