BRAGA

02 Writing02-02 Notes02-02-277

Logarithm (Base a)

Published 16 Apr 20269 min read
Contents
  1. 01Deep Breakdown
  2. 02Flowchart
  3. 03Real-world use
  4. 04The formula, piece by piece
  5. 05The formula in words
  6. 06Critical Concepts
  7. 07Step-by-step calculation (tiny example)
  8. 08Code examples
ddx(log⁡ax)=1xln⁡a\frac{d}{dx}(\log_a x) = \frac{1}{x \ln a}
(1)

Deep Breakdown

What it tells me (Situation Awareness): The derivative of log⁡ax\log_a x (logarithm base aa) is 1/(xln⁡a)1/(x \ln a). This is the generalization of d/dx(ln⁡x)=1/xd/dx(\ln x) = 1/x: the natural log ln⁡x=log⁡ex\ln x = \log_e x has ln⁡e=1\ln e = 1, so the factor 1/ln⁡a1/\ln a disappears. For base a=2a = 2 (bits): d/dx(log⁡2x)=1/(xln⁡2)=1/(0.693x)d/dx(\log_2 x) = 1/(x \ln 2) = 1/(0.693x), about 1.441.44 times larger than the natural log derivative at the same xx. For base a=10a = 10: d/dx(log⁡10x)=1/(xln⁡10)≈1/(2.303x)d/dx(\log_{10} x) = 1/(x \ln 10) \approx 1/(2.303 x), smaller than the natural log derivative. In DA/DS: base-22 logarithms appear in information theory (entropy in bits), base-1010 in decibels and order-of-magnitude analyses, and this derivative is needed when differentiating information-theoretic loss functions written in non-natural-log bases.

Flowchart

f(x) = log_a(x)Change of base:log_a(x) = ln(x) /ln(a)d/dx(ln(x) / ln(a))= (1/x) / ln(a) =1/(x * ln(a))Because ln(a) isa constant withrespect to xSpecial casea=e: ln(e)=1,recovers d/dx(lnx) = 1/xChain rule:d/dx(log_a(f(x)))= f'(x) / (f(x) *ln(a))Domain: x 0; a0, a != 1Larger ln(a)(larger base) =smallerderivative atsame x

Real-world use

Where it is used

Differentiating Shannon entropy H=−∑ipilog⁡2piH = -\sum_i p_i \log_2 p_i with respect to pip_i: dH/dpi=−(1+log⁡2pi)=−(1+ln⁡pi/ln⁡2)dH/dp_i = -(1 + \log_2 p_i) = -(1 + \ln p_i/\ln 2), using d/dp(log⁡2p)=1/(pln⁡2)d/dp(\log_2 p) = 1/(p \ln 2). Differentiating mutual information expressions. Gradient of log-likelihood when the model uses log⁡10\log_{10} for interpretability. Change-of-base in information-theoretic optimization problems.

Problem it solves

When a loss function or metric is expressed in base-2 or base-10 logarithms (e.g., bits of entropy, nats vs bits conversion, decibel-scale regression), the gradient must be computed for optimization. Using the wrong base in the derivative introduces a constant-factor error equal to ln⁡a\ln a.

How it solves the problem

Change-of-base formula: log⁡ax=ln⁡x/ln⁡a\log_a x = \ln x / \ln a. Since ln⁡a\ln a is a constant (not depending on xx), d/dx(log⁡ax)=(d/dx(ln⁡x))/ln⁡a=(1/x)/ln⁡a=1/(xln⁡a)d/dx(\log_a x) = (d/dx(\ln x)) / \ln a = (1/x) / \ln a = 1/(x \ln a).

Example in a business

A DS computes the gradient of binary cross-entropy loss expressed in bits: L=−[ylog⁡2p+(1−y)log⁡2(1−p)]L = -[y \log_2 p + (1-y) \log_2(1-p)]. The gradient: dL/dp=−[y/(pln⁡2)−(1−y)/((1−p)ln⁡2)]=−[y(1−p)−p(1−y)]/(p(1−p)ln⁡2)dL/dp = -[y/(p \ln 2) - (1-y)/((1-p)\ln 2)] = -[y(1-p) - p(1-y)]/(p(1-p)\ln 2). Compared to the natural-log version, it differs by exactly 1/ln⁡2≈1.44271/\ln 2 \approx 1.4427. This constant factor affects the effective learning rate but not the direction of optimization.

The formula, piece by piece

  • log⁡ax\log_a x: logarithm base aa; defined for x>0x > 0, a>0a > 0, a≠1a \ne 1
  • ln⁡a\ln a: natural log of the base; constant w.r.t. xx; always positive for a>1a > 1 (negative for 0<a<10 < a < 1)
  • 1/(xln⁡a)1/(x \ln a): the derivative; has the same 1/x1/x structure as the natural log, scaled by 1/ln⁡a1/\ln a
  • Change of base: log⁡ax=ln⁡x/ln⁡a⇒d/dx(log⁡ax)=(1/x)/ln⁡a\log_a x = \ln x / \ln a \Rightarrow d/dx(\log_a x) = (1/x)/\ln a
  • Special cases: a=e⇒ln⁡e=1⇒d/dx(ln⁡x)=1/xa = e \Rightarrow \ln e = 1 \Rightarrow d/dx(\ln x) = 1/x; a=2⇒d/dx(log⁡2x)=1/(xln⁡2)≈1.4427/xa = 2 \Rightarrow d/dx(\log_2 x) = 1/(x \ln 2) \approx 1.4427/x; a=10⇒d/dx(log⁡10x)=1/(xln⁡10)≈0.4343/xa = 10 \Rightarrow d/dx(\log_{10} x) = 1/(x \ln 10) \approx 0.4343/x
  • Chain rule: d/dx(log⁡af(x))=f′(x)/(f(x)ln⁡a)d/dx(\log_a f(x)) = f'(x)/(f(x) \ln a)
  • Integral: ∫1/(xln⁡a)dx=log⁡ax+C\int 1/(x \ln a) dx = \log_a x + C

The formula in words

"The derivative of log⁡ax\log_a x is 11 over xx times the natural log of the base. The factor 1/ln⁡a1/\ln a converts from natural log units to base-aa units. When the base is ee, this factor is 11 and you get the natural log derivative. For other bases, it's a constant rescaling." Tiny examples: d/dx(log⁡2x)∣x=1=1/(1⋅ln⁡2)≈1.4427d/dx(\log_2 x)|_{x=1} = 1/(1 \cdot \ln 2) \approx 1.4427. d/dx(log⁡10x)∣x=1=1/(1⋅ln⁡10)≈0.4343d/dx(\log_{10} x)|_{x=1} = 1/(1 \cdot \ln 10) \approx 0.4343. d/dx(ln⁡x)∣x=1=1/1=1d/dx(\ln x)|_{x=1} = 1/1 = 1. d/dx(log⁡2(3x))∣x=2=3/((3⋅2)⋅ln⁡2)=3/(6ln⁡2)≈0.7213d/dx(\log_2(3x))|_{x=2} = 3/((3 \cdot 2) \cdot \ln 2) = 3/(6 \ln 2) \approx 0.7213.

Critical Concepts

  • The base matters for magnitude, not direction: all log functions increase with xx (for a>1a > 1), so all derivatives are positive. But the magnitude scales inversely with ln⁡a\ln a: larger base ⇒\Rightarrow smaller derivative at the same xx.
  • Optimization is base-independent: gradient descent with a base-aa log loss will converge to the same minimum as with the natural log, because the derivative differs only by a constant 1/ln⁡a1/\ln a, which just rescales the effective learning rate. For optimization, always use ln⁡\ln internally and apply the base-aa formula only when the output needs to be in specific units.
  • Entropy gradient: dH/dpi=−(log⁡api+1/ln⁡a)dH/dp_i = -(\log_a p_i + 1/\ln a) for Shannon entropy in base aa. The 1/ln⁡a1/\ln a term comes from d/dp(pilog⁡api)=log⁡api+1/ln⁡ad/dp(p_i \log_a p_i) = \log_a p_i + 1/\ln a (product rule).
  • Conversion factor: log⁡ax=log⁡bx/log⁡ba\log_a x = \log_b x / \log_b a for any base bb. The derivative of any log base aa is the natural log derivative scaled by 1/ln⁡a1/\ln a. This factor is: 1/ln⁡2≈1.44271/\ln 2 \approx 1.4427 (nats to bits), 1/ln⁡10≈0.43431/\ln 10 \approx 0.4343 (nats to decibels).
  • Negative ln⁡a\ln a for 0<a<10 < a < 1: when 0<a<10 < a < 1, ln⁡a<0\ln a < 0 and the derivative 1/(xln⁡a)<01/(x \ln a) < 0 for x>0x > 0.

This is correct: log⁡ax\log_a x is a decreasing function when 0<a<10 < a < 1.

Step-by-step calculation (tiny example)

Differentiate f(p)=−plog⁡2pf(p) = -p \log_2 p (contribution to binary entropy) and evaluate at p=0.25p = 0.25.

Step 1: Product rule. f′(p)=−[log⁡2p+p⋅d/dp(log⁡2p)]f'(p) = -[\log_2 p + p \cdot d/dp(\log_2 p)].

Step 2: Apply d/dp(log⁡2p)=1/(pln⁡2)d/dp(\log_2 p) = 1/(p \ln 2). f′(p)=−[log⁡2p+p⋅1/(pln⁡2)]=−[log⁡2p+1/ln⁡2]f'(p) = -[\log_2 p + p \cdot 1/(p \ln 2)] = -[\log_2 p + 1/\ln 2].

Step 3: Evaluate at p=0.25p = 0.25. log⁡2(0.25)=log⁡2(2−2)=−2\log_2(0.25) = \log_2(2^{-2}) = -2. 1/ln⁡2≈1.44271/\ln 2 \approx 1.4427. f′(0.25)=−[(−2)+1.4427]=−[−0.5573]=0.5573f'(0.25) = -[(-2) + 1.4427] = -[-0.5573] = 0.5573. Interpretation: the entropy contribution from pi=0.25p_i = 0.25 increases if pip_i increases slightly (slope is positive at p=0.25p = 0.25).

Code examples

Beginner example (Python)

python
import numpy as np

def log_base_a_deriv(a: float, x: float) -> float:
    """d/dx(log_a(x)) = 1 / (x * ln(a)). Requires x > 0, a > 0, a != 1."""
    if x <= 0:
        raise ValueError(f"x = {x} <= 0: log undefined.")
    if a <= 0 or a == 1:
        raise ValueError(f"a = {a} invalid: need a > 0, a != 1.")
    return 1.0 / (x * np.log(a))   # Compare derivatives for different bases at
x = 1
print("d/dx(log_a(x)) at x=1 for different bases:")
print(f"{'Base a':>8} {'ln(a)':>10} {'Derivative at x=1':>20}")
for a in [2.0, np.e, 10.0, 100.0]:
    deriv = log_base_a_deriv(a, 1.0)
print(f"{a:>8.4f} {np.log(a):>10.6f} {deriv:>20.6f}")   # Shannon entropy gradient

def entropy_gradient(p: np.ndarray, base: float = 2.0) -> np.ndarray:
    """d/dp(-p * log_a(p)) = -(log_a(p) + 1/ln(a))."""
    return -(np.log(p) / np.log(base) + 1.0 / np.log(base))
print("\nShannon entropy gradient d/dp(-p*log2(p)):")
for p in [0.1, 0.25, 0.5, 0.75, 0.9]:
    grad = entropy_gradient(np.array([p]))[0]
print(f" p={p:.2f}: d/dp(-p*log2(p)) = {grad:.4f}")

Beginner example (R)

r
# d/dx(log_a(x)) = 1 / (x * log(a)) [log() in R is natural log]
log_base_a_deriv <- function(a, x) 1 / (x * log(a))
cat("d/dx(log_a(x)) at x=1 for different bases:\n")
cat(sprintf("%-8s %-10s %-20s\n", "Base a", "ln(a)", "Derivative at x=1"))
for (a in c(2, exp(1), 10, 100)) { cat(sprintf("%-8.4f %-10.6f %-20.6f\n", a, log(a), log_base_a_deriv(a, 1)))
}  # Binary entropy and its gradient
binary_entropy_grad <- function(p) -(log(p)/log(2) + 1/log(2))
cat("\nBinary entropy gradient d/dp(-p*log2(p)):\n")
for (p in c(0.1, 0.25, 0.5, 0.75, 0.9)) { cat(sprintf(" p=%.2f: %.4f\n", p, binary_entropy_grad(p)))
}

Professional example (Python)

python
import numpy as np
from scipy.special import entr
np.random.seed(42)   # -- Information-theoretic loss: cross-entropy in bits vs nats --
# Use case: a DA computes KL divergence in bits and needs to verify that
# optimizing in nats vs bits gives the same argmin but different gradient magnitudes.

def cross_entropy_bits(p_true: np.ndarray, p_pred: np.ndarray) -> float:
    """H(P, Q) = -sum_i p_i * log_2(q_i). Cross-entropy in bits."""
    p_pred_safe = np.clip(p_pred, 1e-10, 1.0)
    return float(-np.sum(p_true * np.log2(p_pred_safe)))

def cross_entropy_nats(p_true: np.ndarray, p_pred: np.ndarray) -> float:
    """H(P, Q) = -sum_i p_i * ln(q_i). Cross-entropy in nats."""
    p_pred_safe = np.clip(p_pred, 1e-10, 1.0)
    return float(-np.sum(p_true * np.log(p_pred_safe)))

def cross_entropy_bits_gradient(p_true: np.ndarray, p_pred: np.ndarray) -> np.ndarray:
    """d/d(q_i)(-p_i * log_2(q_i)) = -p_i / (q_i * ln(2)). Uses d/dx(log_2(x)) = 1/(x * ln(2)). """
    p_pred_safe = np.clip(p_pred, 1e-10, 1.0)
    return -p_true / (p_pred_safe * np.log(2))

def cross_entropy_nats_gradient(p_true: np.ndarray, p_pred: np.ndarray) -> np.ndarray:
    """d/d(q_i)(-p_i * ln(q_i)) = -p_i / q_i."""
    p_pred_safe = np.clip(p_pred, 1e-10, 1.0)
    return -p_true / p_pred_safe   # Softmax probabilities from a small 3-class distribution
K = 5
p_true = np.array([0.4, 0.3, 0.15, 0.1, 0.05])   # target distribution
p_pred = np.array([0.3, 0.25, 0.2, 0.15, 0.1])   # predicted distribution (unnormalized after softmax)
grad_bits = cross_entropy_bits_gradient(p_true, p_pred)
grad_nats = cross_entropy_nats_gradient(p_true, p_pred)
ce_bits = cross_entropy_bits(p_true, p_pred)
ce_nats = cross_entropy_nats(p_true, p_pred)
print("Cross-Entropy in Bits vs Nats: d/dq(-p*log_a(q)) = -p/(q * ln(a))")
print(f"\nCross-entropy: {ce_bits:.6f} bits = {ce_nats:.6f} nats")
print(f"Conversion: {ce_bits:.6f} / {ce_nats:.6f} = {ce_bits/ce_nats:.6f} (should = log2(e) = {np.log2(np.e):.6f})")
print(f"\n{'i':>3} {'p_true':>8} {'p_pred':>8} {'grad (bits)':>14} {'grad (nats)':>14} {'ratio':>8}")
for i in range(K):
    ratio = grad_bits[i] / grad_nats[i]
print(f"{i+1:>3} {p_true[i]:>8.3f} {p_pred[i]:>8.3f} {grad_bits[i]:>14.6f} {grad_nats[i]:>14.6f} {ratio:>8.5f}")
print(f"\nGradient ratio (bits/nats) = 1/ln(2) = {1/np.log(2):.6f} (constant, as expected)")
print(f"Key: optimizing bits cross-entropy = optimizing nats cross-entropy (same argmin, scaled gradient)")

Source: domain knowledge

#calculus#differential-calculus#table-of-standard-derivatives

Keyboard shortcuts

Single keys, ignored while typing in a field or with Cmd, Ctrl or Alt held.

0
Home
1 2 3 4
Work, Writing, Tools, About
j / k
Next / previous section on this page
n / p
Next / previous project or essay
u
Up one level
l
Deutsch
t
Light or dark theme
?
This list
Esc
Close