有个同学在群里问,说 MATLAB 里找不到 ln,只有 log,是不是版本不对。其实不是,MATLAB 从一开始就把自然对数叫做 log,没有单独的 ln 函数。这一点和很多计算器、Excel 的习惯不一样,所以从别处转过来的人容易在这里停一下。

三个对数函数各管什么

  • log(x):自然对数,底数是 e,等于数学里的 ln。
  • log2(x):以 2 为底,做算法复杂度、二进制相关计算时常用。
  • log10(x):以 10 为底,画对数坐标、算分贝时用。
log(exp(1))    % 1
log2(8)        % 3
log10(1000)    % 3

反过来,e 的幂用 exp(x),不要写成 e^x 再指望它精确,e 本身只是个近似常量。

任意底数要自己换底

MATLAB 没有 log 的第二个参数,想要以 a 为底,用换底公式:

log_a = @(x, a) log(x) ./ log(a);
log_a(81, 3)   % 4

写成匿名函数以后就能反复用,比每次手写省事。注意这里是 ./,标量除以标量倒无所谓,但输入是向量时必须用点除。

矩阵、向量和逐元素

log 作用在数组上是逐元素的,这点和 sin、sqrt 一致,不需要加点。但如果你传入的是方阵又想要矩阵对数,那是另一个函数 logm,两者结果完全不同,别用错。

A = [1 2; 3 4];
log(A)    % 逐元素
logm(A)   % 矩阵对数,结果一般是复数

负数、零和复数

log(0) 返回 -Inf,不会报错,但后续参与计算会把整条数据变成 Inf。log(-1) 返回 0 + 3.1416i,因为 MATLAB 默认在复数域里算。如果你的数据本来不该出现负值,最好先检查数据来源,而不是靠 abs 掩盖问题。

做信号处理时经常遇到这种情况:功率谱里有零,取对数后全是 -Inf,画图时整条线断掉。常用做法是加一个很小的 eps,或者先把零替换成一个下限值。

数值精度的一个小技巧

当 x 很接近 0 时,log(1+x) 直接算会有精度损失,MATLAB 提供了 log1p(x),专门处理这种场景。做小量近似、金融收益率累加时用得上。

x = 1e-16;
log(1 + x)   % 0
log1p(x)     % 1.0000e-16

顺带说一句,log 的结果默认是 double,如果数据量大又只需要单精度,可以显式转 single 省内存,但精度会掉到 7 位左右。

总结下来就一句话:MATLAB 的 log 就是自然对数,底数不是 e 的时候用换底公式,矩阵对数记得用 logm。