答案 0 :(得分:2)
这是超越等式
我认为真实域在这种情况下你不能将未知与它分开(一般而言),你仍然可以用数字方式解决它(如你所愿)
我懒得对2a.sinh(h/2a)=sqrt(s.s-v.v)
进行适当的分析
但如果我看到它正确,那么2a.sinh(h/2a)
是单调的,所以让c=sqrt(s.s-v.v)
为了简单和加快。正如我所看到的那样c >= 0
所以如果h >= 0
那么a = <0,+inf)
找到价值交叉
double a0,a1,da=initial accuracy step;
for (a1=0.0;2a.sinh(h/2a)<=sqrt(s.s-v.v);a1+=da);
现在a1
拥有近似的顶部绑定解决方案
for (a0=a1;2a.sinh(h/2a)>sqrt(s.s-v.v);a0-=da);
现在a0
拥有近似的低限解
以所需的准确度找到解决方案
如果a0==a1
,那么您已找到确切的解决方案,请停止
如果fabs(a1-a0)<=accuracy
你在准确性范围内,那么停止并降低da
例如da*=0.01;
,这将提高准确度100
次。现在再次搜索解决方案,但仅在间隔<a0,a1>
上搜索解决方案并重复此操作直到找到解决方案
<强> [注释] 强>
超越方程解的另一个例子是:solving Kepler`s equation。当没有其他工作时你仍然可以试试这个:
答案 1 :(得分:2)
你可以先用b = a / h代替。那会把你的等式变成
2b * sinh(1 /(2b))= sqrt(s²-v²)/ h
这样你就可以在右手边看到所有的输入,在左手边看到变量,但遗憾的是,它仍然以超然的形式出现在几个地方。好处是我们现在可以将右侧视为单个数字,以便对此功能有所了解。
这个功能似乎表现得相当好:
所以你可以做standard numerical root-finding methods,例如Newton's method,找到此函数获取给定值的位置(即您从右侧计算的值)。如果您将根查找解释为查找函数为零的位置,那么您要为其找到零的函数就是差异,即
2a * sinh(h /(2a)) - sqrt(s²-v²)
如果您想使用numeric.js,numeric.uncmin
可能是您最好的选择。至少它是迄今为止我在文档中找到的最好的。 (也许在那里有一些裸根发现实现,但如果是这样,我还是找不到它。)你试着找到函数的最小值
(2a * sinh(h /(2a)) - sqrt(s²-v²))²
被解释为a的函数,并希望该最小值实际上(接近)为零。通过将该函数的梯度(导数)作为单独的参数提供,可以获得更好的结果(即更快的收敛和/或更低的误差)。您可以use Wolfram Alpha找到该衍生产品。
让我们将f定义为f(b)= 2b * sinh(1 /(2b))。您试图找出f假定给定值的位置。为了使收敛更快,您可以尝试将此f转换为接近线性的不同函数。四处乱哄乱,我想出了这个:
g(b)=(f(b)-1)^( - 1/2)
您可以将相同的转换应用于右侧,以查看此功能的所需值。对于b> 0.06这看起来相当线性,所以它应该非常快速地收敛。如果您的参数预计在几乎是线性的范围内,但即使对于较小的 b ,它也不应该比原始配方差。您可以使用线性形式计算牛顿方法的起始位置,但我不会打扰:只要您从一个相当大的值开始,牛顿方法的第一步就是这样做。