C++ 牛顿&x2013;当一个函数几乎为“0”时,拉斐逊方法是不可能的;“平坦”;
我正在尝试计算x^x的值。C++ 牛顿&x2013;当一个函数几乎为“0”时,拉斐逊方法是不可能的;“平坦”;,c++,math,double,numeric,C++,Math,Double,Numeric,我正在尝试计算x^x的值。 我已经计算了它的导数,我是 使用牛顿-拉斐逊法求给定a的f(x)=x^x-a的根。 这是我用来计算下一个近似值的函数: double xkp1(double xk, double a){ double lnxp1 = log(xk) +1; return xk -( (fx(xk, a)) / (exp(xk*log(xk)) * (log(xk) + 1) )); } 其中,函数fx的定义如下: double fx(double x, dou
我已经计算了它的导数,我是
使用牛顿-拉斐逊法求给定a的f(x)=x^x-a的根。
这是我用来计算下一个近似值的函数:
double xkp1(double xk, double a){
double lnxp1 = log(xk) +1;
return xk -( (fx(xk, a)) / (exp(xk*log(xk)) * (log(xk) + 1) ));
}
其中,函数fx的定义如下:
double fx(double x, double a){
return exp(x*log(x))-a;
}
现在,只有当xk的起始值已经接近根时,这种方法才能正常工作。如果它相差+-0.5,xk就爆炸到一个非常高的值,f(x)变成无穷大。
现在我想这里可能有什么问题-x^x的导数与x^x的实际值相比非常小,所以整个
(fx(xk,a))/(exp(xk*log(xk))*(log(xk)+1))
变成+无穷大-切线超出了根。这意味着我需要更高的双精度,但有可能吗?如果没有,可以修改方法中的某些内容以使其适用于这种情况吗?我假设您只对正
x
值感兴趣,而不是负整数(也有实数)
我有两个解决方案可以帮助你解决你的问题。首先,如果首先使用对数变换,数值格式可能更稳定。然后,您的等式将是找到a
,这样x log(x)=log(a)
。x log(x)
的导数是log(x)+1
,它可能比指数函数更稳定
否则,您可以使用您所知道的f(x)=x^x
在x>1/e
上单调递增来运行对分搜索。从x_l=1/e
和x_r=2/e
开始。如果f(x_l)>a
,则没有解决方案。然后,当f(x_r)
时,设置x_l=x_r
和x_r=c*x_r
(或增加x_r
的任何其他方案)。一旦你有了一对紧跟在f(x\u l)
之后的x\u l,x\u r
,你就可以开始对分搜索,找到一个包含f(x)=a的解的小区间。一旦这个间隔足够小,你就可以从牛顿方法的迭代开始了
您甚至可以将上述两种方法结合起来,执行对分搜索,以求解x log(x)=log(a)
您对a
的测试值是多少?另外,您可以取两边的对数,然后解出x*log(x)=log(a)
——远不太可能过冲,最终得到天文值。