我正致力于行星运动的3D模拟。我需要解决等式
np * t = x - e * sin(x)
在解决的那一刻,我知道np,t和e的值。 对于每个行星np(角速度)和e(行星轨道的偏心率)。 所以我需要在每个时刻解决这个等式,以了解行星的坐标。 t从1变为某个数字,比方说50。
我选择了牛顿方法,迭代数组的第一个值为np * t,并进行10次迭代。 我用wolframalpha检查代码的结果。 所以这是问题所在。对于50个t值(从1到50),我得到几乎所有正确的值。三个四个结果被误认为是最大1(它是可接受的)但是对于值12,(12 * 04 = x - 11 * sin(x),输入参数)我犯了很大的错误。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
/* np*t = E - e*sin(E)*/
/* 0 = E - e*sin(E) - np*t */
double f(double np, double t, double e, double E){
return E - e*sin(E) - np*t;
}
double f_prim(double np, double t, double e, double E){
return 1.0 - e*cos(E);
}
double newton(double np, double t, double e){
double xk = np*t, xk1;
int i = 0;
while(i < 10){
xk1 = xk - f(np, t, e, xk)/f_prim(np,t,e,xk);
xk = xk1;
i++;
}
return xk1;
}
int main(int argc, char** argv){
int i=12;
for(i = 0; i < 50; i++){
printf("Solution %d %.5f \n", i, newton(0.4,1.0*i,11.0));
}
return 0;
}
12的程序返回值是
解决方案12 41.00415
方程的最大解是14,6
有人能告诉我为什么我有12个大错误,以及如何解决它
编辑: 固定的迭代次数用于调试目的(对于100次迭代也是如此:()
EDIT2: 我在调用牛顿方法时错放了值的顺序。因此,e * sin(x)不应该在-.95和.95之间,但是要大得多,所以我得到的是一个非常小的衍生物,它在分裂时犯了错误。
答案 0 :(得分:2)
牛顿方法对迭代初始值的选择非常敏感。在这种情况下,初始值4.8使函数的导数非常小。除以非常值会导致方法在第一次迭代时过度拍摄:
x 1 = 4.8 - (4.8 - 11 sin(4.8) - 4.8)/(1 - 11 cos(4.8))= -287.321177325
此函数上下移动很多,因此该方法可能永远不会与此初始值收敛。您可以应用多种技巧中的一种来选择更好的技巧:
答案 1 :(得分:0)
如果方程有多个根,则无法确定从牛顿方法得到哪个根。由于你正在使用trig函数,你可能会有无穷多的根等式(编辑添加'可能',从注释中,问题中的等式具有有限数量的根)。
我很想将之前的结果用于xk的初始值而不是np * t。
您可以以图形方式显示计算,以验证是否确定了正确的根。
但这可能是数学堆栈交换网站上最好的问题。