Python对数函数

3

我正在寻找一个Python中关于对数运算的例子。我已经尝试过sympynumpy,但仍然无法实现我想要的效果。例如,对于这样的输入:

log(x+1)+log(4-x)=log(100) # it's just an example 

输出应该给我x的值。我需要用任何其他函数来做到这一点,比如log(x+1)=4log(x)-log(x+1)=log(x)

有没有某种方法或地方(文档或类似)可以找到如何做到这一点?


1
如果你无法通过数学方法解决问题,那就使用编程方法。你的实际问题是什么? - Henry Gomersall
1
对数和指数是互逆函数。当你有类似于 log(x+1)+log(4-x)=log(100) 这样的问题时,你可以通过使用对数定律来解决这个问题。log(x+1) + log(x-4) = log((x+1)*(x-4)) 然后 log((x+1)*(x-4)) = log(100) => (x+1)*(x-4) = 100 这只是一个二次方程,很容易解决。在开始使用重量级数值解法技术之前,请确保您不能仅使用简化的数学变换来解决问题。 - shuttle87
@cdhagmann 不,不会这样的。 - asmeurer
@asmeurer 不,评论者认为你应该使用正确的工具来完成工作——至少在问题描述不清楚的情况下,计算机可能不是正确的工具。 - Henry Gomersall
如果你不熟悉计算机代数系统,也许会有这种看法。但答案应该明确表明计算机是这项工作的绝佳工具。 - asmeurer
显示剩余3条评论
3个回答

9

我可能误解了您需要做的事情,因为您已经尝试过sympy。然而,看起来您只是想解一个代数方程中的x。

在这个方程中解x:

log(x+1)+log(4-x)=log(100)

使用sympy将会是一个不错的选择。

>>> from sympy import Symbol, solve, log
>>> x = Symbol('x')
>>> solve(log(x+1) + log(4-x) - log(100), x)
[3/2 - 5*sqrt(15)*I/2, 3/2 + 5*sqrt(15)*I/2]

如果您想的话,可以使用numpy检查这两个解决方案是否正确。

>>> import numpy as np
>>> a = 3/2 - 5*np.sqrt(15)*1j/2
>>> b = 3/2 + 5*np.sqrt(15)*1j/2
>>> np.log(a + 1) + np.log(4-a)
(4.6051701859880918+0j)
>>> np.log(b + 1) + np.log(4-b)
(4.6051701859880918+0j)
>>> np.log(100)
4.6051701859880918

这不是你在寻找的吗?


1

由于log是一个非线性函数,您需要使用非线性求解器,如scipy.optimize.fsolve。它接受一个函数和一个猜测值,并以数组形式返回答案。出于简单起见,我将该函数定义为lambda函数,因为我们不需要在此行之外使用它,但使用标准的def方法创建函数也可以。后端的[0]从数组中获取值,以返回仅为浮点数。

import scipy.optimize
import math

scipy.optimize.fsolve(lambda x: math.log(x+1) - 4, 5)[0] # 5 is guess value
>>> 53.598
# Check
math.exp(4) - 1
>>> 53.598

提供更多关于你正在做的解释。这将仅仅促进复制粘贴而不是理解。 - rayryeng
@rayryeng,根据问题,这就是他们想要的。但我正在编辑它的过程中。 - Chris Hagmann

1

已经给出了好的建议。我只想指出,你也可以在SymPy中检查答案。

>>> L, R = log(x+1)+log(4-x), log(100)
>>> eq = Eq(L, R)
>>> eq
log(-x + 4) + log(x + 1) == log(100)
>>> sol = solve(eq)
>>> [eq.subs(x, i) for i in sol]
[True, True]

因此,在等式形式中,解决方案会自动验证。这并不总是正确的,但您可以使用数值评估来检查值:

>>> f = eq.lhs - eq.rhs; f
log(-x + 4) + log(x + 1) - log(100)
>>> f.subs(x, sol[0])
-log(100) + log(5/2 - 5*sqrt(15)*I/2) + log(5/2 + 5*sqrt(15)*I/2)
>>> _.n()
0.e-124 + 0.e-125*I
>>> f.subs(x, sol[0]).n(chop=True)  # the small numbers can be chopped
0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接