log(x) 的泰勒级数

tai*_*ion 2 python math calculus python-3.x

我正在尝试计算自然对数的泰勒多项式 ln(x),在 Python 中以 a=1 为中心。我正在使用维基百科上给出的系列,但是当我尝试像 ln(2.7) 这样的简单计算而不是给我接近 1 的值时,它给了我一个巨大的数字。有什么明显的我做错了吗?

def log(x):
    n=1000
    s=0
    for i in range(1,n):
        s += ((-1)**(i+1))*((x-1)**i)/i
    return s
Run Code Online (Sandbox Code Playgroud)

使用泰勒级数:

在此处输入图片说明

给出结果: 在此处输入图片说明

编辑:如果有人偶然发现了这个评估某个实数的自然对数的另一种方法是使用数值积分(例如黎曼和、中点规则、梯形规则、辛普森规则等)来评估经常用于定义的积分自然对数;

在此处输入图片说明

Ala*_* T. 6

该系列仅在 x <= 1 时有效。对于 x>1,您将需要不同的系列。

例如这个(在这里找到):

def ln(x): return 2*sum(((x-1)/(x+1))**i/i for i in range(1,100,2))
Run Code Online (Sandbox Code Playgroud)

输出:

ln(2.7)        # 0.9932517730102833

math.log(2.7)  # 0.9932517730102834
Run Code Online (Sandbox Code Playgroud)

请注意,随着 x 变大,收敛需要 100 多个项(达到不切实际的程度)

您可以通过添加 x 的较小因子的对数来弥补这一点:

def ln(x):
    if x > 2: return ln(x/2) + ln(2)  # ln(x) = ln(x/2 * 2) = ln(x/2) + ln(2)
    return 2*sum(((x-1)/(x+1))**i/i for i in range(1,1000,2))
Run Code Online (Sandbox Code Playgroud)

您也可以在基于泰勒的函数中执行此操作以支持 x>1:

def log(x):
    if x > 1: return log(x/2) - log(0.5) # ln(2) = -ln(1/2)
    n=1000
    s=0
    for i in range(1,n):
        s += ((-1)**(i+1))*((x-1)**i)/i
    return s
Run Code Online (Sandbox Code Playgroud)

当 x 接近零时,这些系列还需要更多项来收敛,因此您可能希望在另一个方向上工作,以保持实际计算值在 0.5 和 1 之间:

def log(x):
    if x > 1:   return log(x/2) - log(0.5) # ln(x/2 * 2) = ln(x/2) + ln(2)
    if x < 0.5: return log(2*x) + log(0.5) # ln(x*2 / 2) = ln(x*2) - ln(2) 
    ...
Run Code Online (Sandbox Code Playgroud)

如果性能是一个问题,您需要将 ln(2) 或 log(0.5) 存储在某处并重用它而不是在每次调用时计算它

例如:

ln2 = None
def ln(x):
    if x <= 2:
        return 2*sum(((x-1)/(x+1))**i/i for i in range(1,10000,2))
    global ln2
    if ln2 is None: ln2 = ln(2)    
    n2 = 0
    while x>2: x,n2 = x/2,n2+1
    return ln2*n2 + ln(x)
Run Code Online (Sandbox Code Playgroud)