newton与二分法的javascript实现
出于好奇,我想证实牛顿确实比牛顿快 对分(对于成功收敛的情况)用于求解非线性方程 我在newton与二分法的javascript实现,javascript,performance,numerical,newtons-method,bisection,Javascript,Performance,Numerical,Newtons Method,Bisection,出于好奇,我想证实牛顿确实比牛顿快 对分(对于成功收敛的情况)用于求解非线性方程 我在教科书中实现了这两种算法。 测试的功能是: f(x) = 5*(x-0.4)*(x^2 - 5x + 10), with a simple real root 0.4 收敛精度设置为1e-4。 牛顿开始于x0=0.5,在两次迭代中收敛。 二分法以间隔[0,1]开始,在14次迭代中收敛 我使用performance.now()来测量这两种方法的运行时间。 令人惊讶的是,经过多次尝试,牛顿总是比二分法慢 New
教科书中实现了这两种算法。
测试的功能是:
f(x) = 5*(x-0.4)*(x^2 - 5x + 10), with a simple real root 0.4
收敛精度设置为1e-4。
牛顿开始于x0=0.5
,在两次迭代中收敛。
二分法以间隔[0,1]
开始,在14次迭代中收敛
我使用performance.now()
来测量这两种方法的运行时间。
令人惊讶的是,经过多次尝试,牛顿总是比二分法慢
Newton time: 0.265 msec: [0.39999999988110857,2]
bisection time: 0.145 msec: [0.399993896484375,14]
我将程序移植到C(visual C):牛顿比二分法快得多
Newton time: 0.265 msec: [0.39999999988110857,2]
bisection time: 0.145 msec: [0.399993896484375,14]
这些数字代码非常简单,我看不出有什么奇怪的事情发生。
有人能帮忙吗
n次多项式的Horner方法
功能评估(a,t){
//f(x)=a0+a1x+…+anxn
var n=a.length-1;//度(n)
var b=[];
var c=[];
变量i,k;
对于(i=0;i=1;k--){
b[k]=a[k]+t*b[k+1];
c[k]=b[k]+t*c[k+1];
}
b[0]=a[0]+t*b[1];
返回[b[0],c[1];
}
//简单牛顿
函数牛顿(eval,x0,epsilon){
var eps=ε1e-4;
var imax=20;
对于(变量i=0;i0)
返回未定义;
变量xMid、fHi、fLo、fMid;
var-iter=0;
而(xHi-xLo>eps){
++iter;
xMid=(xLo+xHi)/2;
fMid=func(coeff,xMid)[0];//fc
if(数学abs(fMid)[a,c]
xHi=xMid;
fHi=fMid;
}else{//fc*fb<0-->[c,b]
xLo=xMid;
fLo=fMid;
}
}
返回[(xLo+xHi)/2,iter];
}
//f(x)=5x^3-27x^2+60x-20
//=5*(x-0.4)*(x^2-5x+10)
var系数=[-20,60,-27,5];
var t0=performance.now();
var sol1=牛顿(eval,0.5,1e-4);
var t1=performance.now();
var sol0=二等分(eval,[0,1],1e-4);
var t2=performance.now();
console.log('Newton time:'+(t1-t0).toFixed(3)+':'+sol1);
console.log('对分时间:'+(t2-t1).toFixed(3)+':'+sol0);
有许多外部因素会影响测试,包括代码的JIT编译顺序和缓存。在如此少的迭代次数上度量时间并不是很有意义,因为这些外部因素最终可能比您试图度量的要大
例如,如果反转顺序,使其在计算牛顿之前计算二分法,则会得到相反的结果
如果您想做得更好,可以同时运行两个循环一次,然后再运行一个循环以再次运行两个循环N次,并测量运行该循环所需的时间