【问题标题】:Python - How to avoid discrepancy of base y**log base y of x, in gmpy2Python - 如何在 gmpy2 中避免 base y**log base y of x 的差异
【发布时间】:2016-07-27 10:08:42
【问题描述】:

以下代码示例我的问题不会发生在 10 次方 10 和 10 次方 11 之间,但对于代码中给出的示例及其上方的示例。

我看不到我在代码中的哪些地方没有正确处理原始值的检索。可能是我错过了一些简单的事情。

我需要确保我可以从 log x 恢复 x 用于各种基础。与其依赖诸如gmpy2 之类的库函数,是否有任何反向anti-log 算法可以保证例如2**log2(x) 它会给出x

我可以看到如何直接开发日志,但不知道如何返回,例如,泰勒级数需要很多术语...How can I write a power function myself?和@dan04 回复。代码如下。

from gmpy2 import gcd, floor, next_prime, is_prime    
from gmpy2 import factorial, sqrt, exp, log,log2,log10,exp2,exp10    
from gmpy2 import mpz, mpq, mpfr, mpc, f_mod, c_mod,lgamma    
from time import clock    
import random    
from decimal import getcontext
x=getcontext().prec=1000 #also tried 56, 28
print(getcontext())

def rint():#check accuracy of exp(log(x))
    e=exp(1)
    l2=log(2)
    l10=log(10)
    #x=random.randint(10**20,10**21) --replaced with an actual value on next line
    x=481945878080003762113
    # logs to different bases
    x2=log2(x)
    x10=log10(x)
    xe=log(x)
    # logs back to base e
    x2e=xe/l2
    x10e=xe/l10
    #
    e2=round(2**x2)
    e10=round(10**x10)
    ex=round(e**xe)
    #
    ex2e=round(2**x2e)
    ex10e=round(10**x10e)
    error=5*x-(e2+e10+ex+ex2e+ex10e)
    print(x,"error sum",error)
    #print(x,x2,x10,xe)
    #print(x2e,x10e)
    print(e2,e10,ex)
    print(ex2e,ex10e)
 rint()

【问题讨论】:

  • 首先,我不知道您是如何让random.randint 处理这些限制的。它不在我的机器上......但无论如何我怀疑这与浮点算术精度有关。
  • 我认为你是对的,在这种情况下,我的问题是,我如何解决这个问题,无论是在 python 还是 gmpy2 或其他一些库中?
  • 我可以通过en.wikipedia.org/wiki/Exponentiation_by_squaring描述的方法得到反对数,所以对于log 2来说,不是通过自然对数,而是直接计算log base 2。

标签: python logarithm gmpy


【解决方案1】:

注意:我维护 gmpy2 库。

在您的示例中,您使用的是来自decimal 模块的getcontext()。您不会更改 gmpy2 使用的精度。由于gmpy2 的默认精度为 53 位,而您的 x 值需要 69 位,因此预计您有错误。

这是您示例的更正版本,说明了随着精度的提高累积误差如何变化。

import gmpy2

def rint(n):
    gmpy2.get_context().precision = n
    # check accuracy of exp(log(x))
    e = gmpy2.exp(1)
    l2 = gmpy2.log(2)
    l10 = gmpy2.log(10)
    x = 481945878080003762113
    # logs to different bases
    x2 = gmpy2.log2(x)
    x10 = gmpy2.log10(x)
    xe = gmpy2.log(x)
    # logs back to base e
    x2e = xe/l2
    x10e = xe/l10
    #
    e2 = round(2**x2)
    e10 = round(10**x10)
    ex = round(e**xe)
    #
    ex2e = round(2**x2e)
    ex10e = round(10**x10e)
    error = 5 * x - (e2 + e10 + ex + ex2e + ex10e)
    print("precision", n, "value", x, "error sum", error)

for n in range(65, 81):
    rint(n)

这是结果。

precision 65 value 481945878080003762113 error sum 1061
precision 66 value 481945878080003762113 error sum 525
precision 67 value 481945878080003762113 error sum -219
precision 68 value 481945878080003762113 error sum 181
precision 69 value 481945878080003762113 error sum -79
precision 70 value 481945878080003762113 error sum 50
precision 71 value 481945878080003762113 error sum -15
precision 72 value 481945878080003762113 error sum -14
precision 73 value 481945878080003762113 error sum 0
precision 74 value 481945878080003762113 error sum -2
precision 75 value 481945878080003762113 error sum 1
precision 76 value 481945878080003762113 error sum 0
precision 77 value 481945878080003762113 error sum 0
precision 78 value 481945878080003762113 error sum 0
precision 79 value 481945878080003762113 error sum 0
precision 80 value 481945878080003762113 error sum 0

【讨论】:

    【解决方案2】:

    只要设置十进制模块精度,通常的建议是使用十进制数据类型

    from decimal import Decimal, getcontext
    
    getcontext().prec = 1000
    
    # Just a different method to get the random number:
    x = Decimal(round(10**20 * (1 + 9 * random.random()))) 
    
    x10 = Decimal.log10(x)
    e10 = 10**x10
    
    e10 - x
    #outputs: Decimal('5.2E-978')
    

    对于不同的基数,您可能需要使用对数公式:

    x2 = Decimal.log10(x) / Decimal.log10(Decimal('2'))
    e2 = 2**x2
    
    e2 - x
    #outputs: Decimal('3.9E-978')
    

    【讨论】:

    • 好的,谢谢,这适用于十进制,log10,但是对于“各种基数”,即不同的基数,除自然对数之外的任何整数基数(例如 2),通常什么适用于恢复 x?
    • @ocopa - 查看我对不同基础的编辑。只需使用 log10(x)/log10(base)。
    • 是的,我知道,但我试图弄清楚为什么我从 gmpy2 得到错误的答案,以及底层代码是什么。似乎 gmpy2 在幕后使用了 log base e,或者我们认为可能存在浮点精度问题。在我发布一些有用的参考资料后,我会将其标记为已回答。
    【解决方案3】:

    承认,Aguy 解决了我的问题。 我没有考虑到需要超过 15 位的精度。 这个对另一个问题的回答涵盖了这一点。 gmpy2 log2 not accurate after 16 digits

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-13
      • 2014-03-21
      • 1970-01-01
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多