Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Math 当“项”非常小时,计算log(exp(项)之和)_Math_Sum_Precision_Largenumber_Natural Logarithm - Fatal编程技术网

Math 当“项”非常小时,计算log(exp(项)之和)

Math 当“项”非常小时,计算log(exp(项)之和),math,sum,precision,largenumber,natural-logarithm,Math,Sum,Precision,Largenumber,Natural Logarithm,我想计算log expA1+expA2。 下面的公式 log(exp(A1) + exp(A2) ) = log[exp(A1)(1 + exp(A2)/exp(A1))] = A1 + log(1+exp(A2-A1)) 在A1和A2较大且数值为expA1=Inf或expA2=Inf时有用。 此线程中将讨论此公式-> . 当A1和A2的角色被替换时,公式是正确的 我关心的是当A1和A2非常小的时候。例如,当A1和A2为: A1 <- -40000 A2 <- -45000

我想计算log expA1+expA2。 下面的公式

 log(exp(A1) + exp(A2) ) = log[exp(A1)(1 + exp(A2)/exp(A1))] = A1 + log(1+exp(A2-A1)) 
在A1和A2较大且数值为expA1=Inf或expA2=Inf时有用。 此线程中将讨论此公式-> . 当A1和A2的角色被替换时,公式是正确的

我关心的是当A1和A2非常小的时候。例如,当A1和A2为:

 A1 <- -40000
 A2 <- -45000
使用上述公式得出:

 A1 + log(1 + exp(A2-A1))
 [1] -40000
这是A1的值。 将上述公式与A1和A2的翻转角色进行伊辛,得出:

A2 + log(1 + exp(A1-A2))
[1] Inf
三个值中哪一个最接近logexpA1+expA2的真实值?是否有可靠的方法来计算logexpA1+expA2,当A1、A2较小且A1、A2较大时,可以使用该方法


提前感谢您

您应该使用更精确的方法来进行直接计算

“当[它们]很大时”是没有用的。当差值为负值时,它很有用

当x接近0时,则log1+x约为x。因此,如果A1>A2,我们可以采用您的第一个公式:

log(exp(A1) + exp(A2)) = A1 + log(1+exp(A2-A1))
用A1+expA2-A1来近似,当A2-A1更负时,近似会更好。由于A2-A1=-5000,这比负值大得多,足以使近似值足够


不管怎样,如果y离零太远,无论哪种方式expy都会超过|下溢一个double并导致0或无穷大,这是一个double,对吗?你用什么语言?。这就解释了你的答案。但是由于expA2-A1=exp-5000接近于零,您的答案大约是-40000+exp-5000,这与-40000是无法区分的,因此一个是正确的。

您应该使用更精确的方法来进行直接计算

“当[它们]很大时”是没有用的。当差值为负值时,它很有用

当x接近0时,则log1+x约为x。因此,如果A1>A2,我们可以采用您的第一个公式:

log(exp(A1) + exp(A2)) = A1 + log(1+exp(A2-A1))
用A1+expA2-A1来近似,当A2-A1更负时,近似会更好。由于A2-A1=-5000,这比负值大得多,足以使近似值足够


不管怎样,如果y离零太远,无论哪种方式expy都会超过|下溢一个double并导致0或无穷大,这是一个double,对吗?你用什么语言?。这就解释了你的答案。但是,由于expA2-A1=exp-5000接近于零,您的答案大约是-40000+exp-5000,这与-40000是无法区分的,因此其中一个是正确的。

在如此巨大的指数差异中,您可以在没有任意精度的情况下最安全的方法是

选择最大指数,使其为Am=maxA1,A2 所以:logexpA1+expA2->logexpAm=Am 对于这种情况,这是最接近的 在你的例子中,结果是-40000+delta 三角洲是非常小的东西 如果您想使用第二个公式,那么所有这些都将分解为计算log1+expA

如果A为正,则结果与实际情况相差甚远 如果A为负,那么它将截断为log1=0,因此得到与上面相同的结果 [附注]

您的指数差以^500为基数 单精度32位浮点可存储高达+/-2^+/-128的数字 双精度64位浮点可存储高达+/-2^+/-1024的数字 所以当你的基数是10或e时,这远远不够你所需要的 如果你有四倍的精度,那应该足够了,但是当你再次开始改变经验差时,你会很快达到现在的相同点 [PS]如果您需要更高的精度而不是任意精度

您可以尝试创建自己的数字类 具有数字的内部存储,如number=a^b 其中a,b是浮点数 但为此,您需要编写所有基本函数 *这很容易 +,-这是一场噩梦,但即使是这样,也可能有一些方法/算法
在如此巨大的指数差异中,没有任意精度的情况下,最安全的方法是

选择最大指数,使其为Am=maxA1,A2 所以:logexpA1+expA2->logexpAm=Am 对于这种情况,这是最接近的 在你的例子中,结果是-40000+delta 三角洲是非常小的东西 如果您想使用第二个公式,那么所有这些都将分解为计算log1+expA

如果A为正,则结果与实际情况相差甚远 如果A为负,那么它将截断为log1=0,因此得到与上面相同的结果 [附注]

您的指数差以^500为基数 单精度32位浮点可存储高达+/-2^+/-128的数字 双精度64位浮点可存储高达+/-2^+/-1024的数字 所以当你的基数是10或e时,这远远不够你所需要的 如果你有四倍的精度,那应该足够了,但是当你再次开始改变经验差时,你会很快达到现在的相同点 [PS]如果您需要更高的精度而不是任意精度

您可以尝试创建自己的数字类 具有数字的内部存储,如number=a^b 其中a,b是浮点数 但为此,您需要编写所有基本函数 *这很容易 +是一场噩梦吗 但即使是这样,也可能有一些方法/算法