||
C程序:
double sin_t(double a)
{
double tmp = a,re,tmp2;
char i = 0;
do{
tmp /= 2;
i++;
}while( tmp > ( 0.0001 )); //(1)
re = tmp * tmp;
do{
re = 4 * re * ( 1- re );
}while( --i > 0);//(2)
tmp = re;
do{
tmp2 = tmp;
tmp = tmp / 2 + re / tmp / 2;
}while( tmp2 != tmp);//(3)
return tmp;
}
(1):精度10^-4的运算要求,当然也可修改为其它精度,但需要保证它的2次方在double精度运算以内。这段程序目的把弧度a平分为2的i次幂。通常我们认为function: sin(x)/x 在足够小的情形下值为1。所以当把弧度平分到一个给定的“足够小”量级时,认为sin(x)=x,例如sin(0.000097)= 9.6999999847887833404894502125635e-5,通常的场合下可以直接认为其约等于0.000097。
(2):既然弧度a被平分了i次,倍角公式的变形 (sin(2*x))^2=4*((sin(x))^2)*(1-(sin(x))^2),倍角i次后得到的值也就是所需要求取正弦值的平方了。
(3):既然有了平方,那么值开方就用到这段程序,牛顿迭代求根。x^2-p=0 => x(n+1)=x(n)-((x(n))^2-p)/(2*x(n))=x(n)/2+p/x(n)/2。
注意程序只计算的值默认为正值,具体是正或负,可以在前加入弧度范围的判断即可。
利用sin(x)也可以求得arctan(x)的值,方法也是牛顿迭代(满足迭代条件),tan(x)-p=0 => x(n+1)=x(n)+p*(cos(x(n))^2-sin(x(n))*cos(x(n));
说到迭代,我想起以前写的一个已知劣弧长,弦长,求直径的MATLAB函数;
function R=ac2r(arc,chord)
if (arc/chord)>pi/2 %(1)
R=0;
else
x=1/chord;
for i=1:1000
tmp=x;
x=sin(arc*x)/chord;
if x==tmp
break;
end
end
R=1/x;
end
(1):所求条件须劣弧。这是不动点的求法。
sin(arc/R)=chord/R => x=sin(arc*x)/chord 其中x=1/R。对于式子右方求导(arc/chord)*cos(arc*x) 其值在0<arc*x<pi/2时小于1。arc/chord<arc*x =>(arc/chord)*cos(arc*x)<arc*x*cos(arc*x)。而x*cos(x)当0<x<pi/2时小于“1”。
>> 13.7*sin(0.87)
ans =
10.4713
>> 0.87*13.7
ans =
11.9190
>> ac2r(11.9190,10.4713)
ans =
13.7000
常想,对于某个问题,确定它的最优解法的困难会是有规则的么?判断最优又是依靠什么,对于动则几何级数的复杂度,这些复杂度,起源于少数bit可以描述的问题,颇令人感到讽刺。也许因为所我们(包括问题)存在的宇宙,在交流时所用的语言,它其中包含的信息已经不可思议的庞大了吧。NP……。
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-11-23 08:33
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社