
复合对数函数的导数:链式法则应用示例
对数函数的自变量若不是单独的 x,而是一个由加减乘除、幂函数、三角函数或其他函数构成的表达式,求导时就要用到链式法则。典型形式是 y = ln(u(x))。它的导数为 y' = u'(x) / u(x),前提是所讨论的实数范围内 u(x) > 0。
这条公式简短,却常被误用:有人忘了乘里面函数的导数,有人忽略定义域,还有人把 ln(u) 和 ln|u| 当成同一个函数。本文从基本公式出发,逐步处理常见复合结构、特殊情形和边界,并提供可运行的 Python 代码用于符号求导和数值核对。
一、从链式法则理解对数求导
设 u = u(x),且 u(x) > 0。把外层函数记为 f(t) = ln(t),则 f'(t) = 1/t。由链式法则:
d/dx ln(u(x)) = f'(u(x)) · u'(x) = u'(x) / u(x)
可以把它记成一句话:对数的导数等于“内部函数的导数除以内部函数”。这里的“内部函数导数”不能省略。若内部表达式恰好是 x,则 u'(x)=1,公式退化为 (ln x)'=1/x;若内部表达式更复杂,就必须先对它求导。
例如:
y = ln(3x + 2),则y' = 3/(3x + 2)。y = ln(x² + 1),则y' = 2x/(x² + 1)。y = ln(sin x),则y' = cos x/sin x = cot x,但只在sin x > 0的实数区间内适用。
第三个例子也提醒我们:求导公式和定义域必须一起考虑。即使导数表达式在某些点上看起来有意义,原函数在那些点不一定有定义。
二、常见复合对数函数
1. 对数内部是多项式或代数式
设 y = ln(x² - 4x + 5)。令 u(x) = x² - 4x + 5,则 u'(x)=2x-4,所以
y' = (2x - 4)/(x² - 4x + 5)
分母可写为 (x - 2)² + 1,对所有实数都大于零,因此原函数对所有实数有定义。确认内部表达式的正负,通常是检查实数对数定义域的重要一步。
再看 y = ln((x - 1)/(x + 2))。求导的形式仍是 u'/u。对 u=(x-1)/(x+2) 使用商法则,可得 u'=3/(x+2)²,因此
y' = 3/((x + 2)(x - 1))
但定义域不只是排除分母为零。还必须满足 (x-1)/(x+2) > 0,因此实数定义域为 x < -2 或 x > 1。最终的导数也只在这些区间内描述原函数。
2. 对数内部是幂函数
若 y = ln(xⁿ),不能不加条件地将其直接写成 n ln x。在实数范围内,若 n 是正整数,xⁿ 的正负取决于 n 的奇偶性;奇数次幂在负数处为负,不能作为实数自然对数的输入。若 n 为偶数,除了 x=0 外,xⁿ>0。
直接套用链式法则,在 xⁿ>0 的范围内有
d/dx ln(xⁿ) = n xⁿ⁻¹/xⁿ = n/x
这个结果只对原函数有定义且可导的点成立。若写成 n ln|x|,则它在 x≠0 时有定义,且导数同样为 n/x。但是,ln(xⁿ) 和 n ln|x| 并非总是相同:当 n 为奇数且 x<0 时,前者在实数范围内无定义,后者有定义。
3. 对数内部是三角函数
设 y = ln(1 + cos x)。内部导数是 -sin x,于是
y' = -sin x/(1 + cos x)
也可在允许的区间内用三角恒等式改写,但改写不能改变原函数的定义域。实数自然对数要求 1 + cos x > 0;当 cos x=-1 时内部量为零,原函数无定义。这些点必须从定义域中排除。
4. 对数内部又含对数
复合层数增加时,链式法则仍然逐层应用。比如
y = ln(ln x)
外层对数的输入是 ln x,所以不仅要有 x>0,还要有 ln x>0,即 x>1。求导时:
y' = (1/ln x) · (1/x) = 1/(x ln x)
这里的两个因子分别来自外层和内层。若只写成 1/ln x,就漏掉了内层导数 1/x。
三、常用对数与任意底数
自然对数以 e 为底,常用对数以 10 为底。利用换底公式:
logₐ(u) = ln(u)/ln(a)
当底数 a 是常数,且 a>0、a≠1 时,ln(a) 是常数,因此
d/dx logₐ(u(x)) = u'(x)/(u(x) ln(a))
例如 y = log₁₀(x² + 1),则
y' = 2x/((x² + 1) ln 10)
若底数和真数都随 x 变化,不能把底数当常数。例如 y = logₓ(x + 1)。换底后:
y = ln(x + 1)/ln x
使用商法则可得
y' = [ln x/(x + 1) - ln(x + 1)/x]/(ln x)²
这个实数函数的条件包括 x>0、x≠1,以及对数真数 x+1>0。在已满足 x>0 时,后一条件自动满足。变量底数的公式可以直接由换底公式和商法则得到;若忽略底数的变化,会漏掉一个导数项。
四、定义域、边界与不同对数形式
1. 实数自然对数的输入必须为正
在通常的实数微积分中,ln(u(x)) 要求 u(x)>0。当 u(x)=0 时,ln(u) 没有定义;当 u(x)<0 时,实数自然对数也没有定义。因而 u'/u 不能作为原函数在这些点上的导数。
定义域最好在求导之前或之后明确检查。尤其当内部量是分式、偶次根式、多个因子的乘积或另一个对数时,不能只看最终导数的分母。
2. ln|u(x)| 是另一种常见写法
对 u(x)≠0,函数 ln|u(x)| 在实数范围内有定义,并且
d/dx ln|u(x)| = u'(x)/u(x)
因此,有些教材在对数求导或积分中使用 ln|u|。绝对值并不意味着可以在 u=0 处继续使用公式;那里对数没有定义。更重要的是,ln(u) 和 ln|u| 的实数定义域不同,不能在不说明条件时互换。
3. 端点和不可导点
导数描述的是函数在定义域内部某点附近的变化。若函数只在某个区间的一侧有定义,区间端点处通常不能直接套用普通的双侧导数定义。比如 ln x 在 x=0 处没有定义,因此不存在它在零点的导数;1/x 在零点无意义,也不能被解释成那里存在某种“无穷大的导数”。
如果内部函数本身在某点不可导,复合函数的链式法则也不能仅凭形式公式保证在那里成立。应用公式前,应确认相关函数在所讨论点满足可导条件。
4. 复数对数的额外注意
复数对数与实数对数的定义方式不同。复对数通常具有多值性;在软件和复分析中,常会指定一个分支,例如主值分支。指定分支后,函数通常只在避开分支切线的区域内作为单值解析函数讨论。对数的导数关系可以在相应分支的局部解析区域内使用,但不能把实数的“输入大于零”条件直接搬到复数情形,也不能忽略分支约定。本文后续例子讨论的是实数函数。
五、乘积、商与对数求导法
对数函数经常用于简化乘积和幂的求导。例如令 y = f(x)g(x),在 y>0 的范围内可取对数:
ln y = ln f + ln g
对两边求导,得到 y'/y = f'/f + g'/g,所以
y' = y(f'/f + g'/g)
这就是对数求导法的一种形式。它适合处理许多因子相乘,或变量同时出现在底数和指数中的表达式。但使用时必须检查哪些量为正,确保取对数合法。
例如 y = xˣ 在 x>0 时,可写成 ln y = x ln x。求导得 y'/y = ln x + 1,所以
y' = xˣ(ln x + 1)
这个推导明确依赖 x>0,因为实数 ln x 只在正数处有定义。若问题讨论整数或有理数指数的负底数情形,应单独根据原函数的定义分析,不能无条件沿用这个推导。
对任意非零可导函数,也有 d/dx ln|y| = y'/y。因此在对数求导法中,有时会写 ln|y|,以覆盖 y<0 的区间;仍然必须排除 y=0,并确保在所讨论区间内符号和可导性符合推导需要。
六、可运行的符号求导示例
下面的 Python 示例使用 SymPy,对若干复合对数函数进行符号求导。先安装依赖:
python -m pip install sympy
将以下代码保存为 log_derivative.py,再运行 python log_derivative.py:
import sympy as sp
x = sp.symbols("x", real=True)
examples = {
"ln(x^2 + 1)": sp.log(x**2 + 1),
"ln(3x + 2)": sp.log(3*x + 2),
"ln(ln(x))": sp.log(sp.log(x)),
"log_10(x^2 + 1)": sp.log(x**2 + 1, 10),
}
for name, expr in examples.items():
derivative = sp.diff(expr, x)
print(f"{name}:")
print(" function =", expr)
print(" derivative =", sp.simplify(derivative))
print()
SymPy 的 log 表示自然对数;传入底数时可以表示其他底数。输出形式可能与手算结果不同,例如表达式可能包含 log(10),也可能经过符号化简。等价表达式的外观不必完全一致。
符号系统能够按形式规则求导,但它不一定会替使用者完整记录原函数的实数定义域。比如 ln(ln(x)) 的导数形式是 1/(x*log(x)),而实数原函数的定义域是 x>1。不能因为计算软件输出了导数,就认为它在所有实数点都有意义。
七、数值核对:比较解析导数与差分近似
可以用有限差分对某个定义域内部的点做粗略检查。中心差分公式为 (f(x+h)-f(x-h))/(2h),当 h 足够小且取值没有跨出定义域时,它通常可用于发现明显的符号或系数错误。不过,有限差分有舍入误差,也会受步长影响,不能代替解析证明。
import math
def f(x):
return math.log(x * x + 1)
def analytic_derivative(x):
return 2 * x / (x * x + 1)
x0 = 0.7
h = 1e-6
numeric = (f(x0 + h) - f(x0 - h)) / (2 * h)
analytic = analytic_derivative(x0)
print("中心差分近似:", numeric)
print("解析导数值:", analytic)
print("绝对误差:", abs(numeric - analytic))
这个例子的定义域是全体实数,所以 x0-h 与 x0+h 都能代入。对于 ln(x),如果在靠近零的地方选取步长,必须确保两个采样点都大于零;对于 ln(ln(x)),差分两侧的点都要大于 1。若采样点越过定义域边界,计算报错并非导数公式失效,而是函数值本身无法在该点按实数计算。
八、常见错误与排查方法
- 漏掉内层导数。 把
ln(3x+2)的导数写成1/(3x+2),忽略了内部的导数 3。应固定使用u'/u检查。 - 把分母写错。
(ln u)'的分母是整个内部函数u,不是它的导数;导数是u'/u,而非u/u'。 - 忘记底数因子。 对常数底数
a,应有1/ln(a);只有自然对数不需要额外的底数因子。 - 变量底数被当成常数。 对
logₓ(u(x)),要先换底,再对商求导,底数部分也会贡献变化。 - 把
ln u误写成ln|u|。 二者的实数定义域不同。取绝对值会改变函数,必须确认题目允许这样改写。 - 只看导数,不查原函数定义域。 公式化简后的表达式可能在原函数无定义的点上有形式上的取值,但那不会让原函数在该点突然有导数。
- 忽略多层链式法则。 对
ln(ln x),外层和内层各产生一个因子,结果是1/(x ln x),不是1/ln x。 - 化简时丢失条件。 约分、使用对数恒等式或三角恒等式后,表达式看起来更简单,但原函数的定义域约束仍然有效。
一个实用的自检方法是:先把整个对数真数命名为 u(x),写出 u'(x)/u(x),再单独列出要求 u(x)>0 的范围。若是常数底数的对数,再补上 ln(a);若底数也含 x,则先换底。这个流程能把大多数链式法则遗漏和定义域错误分开处理。
九、适用场景与安全使用说明
复合对数求导常用于研究函数的变化率、优化目标、概率模型中的对数似然,以及乘积形式的尺度变化。例如对正值函数 f(x),f'(x)/f(x) 是其相对变化率;在统计建模中,取对数可以把多个概率因子的乘积变成求和,便于计算和优化。这些都是数学建模用途,不意味着对数变换本身能提供安全保障。
编程时,定义域检查和数值稳定性也需要区分。使用 log1p(z) 计算接近零的实数 z 所对应的 ln(1+z),在一些浮点计算场景下通常比先算 1+z 再取对数更准确;但仍要求数学上的输入满足 1+z>0,它不会自动修复无效输入。使用浮点数时,还要考虑舍入、溢出、下溢和库函数对非法输入的处理方式。
对数不是输入验证、密码保护或访问控制机制。若程序把用户输入送入对数函数,应按业务规则校验输入范围,并妥善处理错误;不要把“取了对数”当作数据变安全或输入可信的依据。若表达式含敏感数据,还应单独评估日志记录、异常信息和数据存储方式,不能由求导公式推断其安全性。
总结
复合自然对数的核心公式是 (ln u(x))' = u'(x)/u(x)。它体现了链式法则:外层导数给出倒数,内层导数负责表达内部变化。常数底数对数还要除以 ln(a);变量底数应先换底;多层对数则逐层相乘。最重要的边界条件是,实数 ln(u) 要求 u>0,而 ln|u| 要求 u≠0。把求导过程与定义域检查配套进行,才能得到既正确又可用的结果。








