BRAGA

02 Writing02-02 Notes02-02-095

Definition

Published 16 Apr 202611 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
y=log⁡ax  ⟺  ay=xy = \log_a x \iff a^y = x
(1)

(where x>0,a>0,a≠1x > 0, a > 0, a \neq 1)

Deep Breakdown

What it tells me (Situation Awareness): The logarithm definition is the biconditional equivalence: y=log⁡axy = \log_a x if and only if ay=xa^y = x. In plain language: the logarithm answers the question "to what power must I raise base aa to get xx?" The output yy is always an exponent. This definition is foundational to every log identity. Domain constraints: x>0x > 0 (argument must be positive), a>0a > 0 and a≠1a \ne 1 (base must be positive and not 1); the output yy is any real number. Special values follow directly: log⁡a1=0\log_a 1 = 0 (since a0=1a^0 = 1), log⁡aa=1\log_a a = 1 (since a1=aa^1 = a), log⁡a(ak)=k\log_a(a^k) = k for any real kk. In DA/DS, this definition is the starting point for: log-likelihood (ln⁡∏pi=∑ln⁡pi\ln \prod p_i = \sum \ln p_i via the definition linking products to sums); cross-entropy loss (−∑yiln⁡p^i-\sum y_i \ln \hat{p}_i); entropy (H=−∑pilog⁡2piH = -\sum p_i \log_2 p_i); logistic regression log-odds (ln⁡p1−p\ln \frac{p}{1-p}); data visualization on log-scale to compress right-skewed distributions; and the Box-Cox transform. The natural logarithm ln⁡=log⁡e\ln = \log_e (base e≈2.71828e \approx 2.71828) is the default in ML/statistics because ee arises naturally in exponential families, the Gaussian distribution, and continuous growth. Base-2 logarithms dominate information theory (bits). Base-10 is used in acoustics and pH.

Flowchart

Question: towhat powermust a be raisedto get x?Definition: y =log_a(x) iff a^y =xDomain: x 0, a0, a ≠ 1; Range:y ∈ ℝSpecial values:log_a(1) = 0,log_a(a) = 1,log_a(a^k) = kNatural log: ln =log_e, e ≈2.71828 —default inML/statsBase-2: bits —Shannonentropy,information gainBase-10: log10— pH scale,decibels,common logsDA:log-likelihood —ln(L) convertsproduct to sumDA:cross-entropyloss — -sum(y *ln(p_hat))DA: log-odds —ln(p/(1-p)) inlogisticregressionTRAP:log_a(x+y) ≠log_a(x) +log_a(y) — suminside log doesNOT split

Real-world use

Where it is used

Log-likelihood maximization: if X1,…,Xn∼Poisson(λ)X_1, \ldots, X_n \sim \text{Poisson}(\lambda), the likelihood is L(λ)=∏i=1ne−λλxixi!L(\lambda) = \prod_{i=1}^n \frac{e^{-\lambda}\lambda^{x_i}}{x_i!}. Direct maximization of this product is numerically unstable for large nn. Taking ln⁡L(λ)=∑i(−λ+xiln⁡λ−ln⁡xi!)\ln L(\lambda) = \sum_i (-\lambda + x_i \ln \lambda - \ln x_i!) converts it to a sum — stable and differentiable. The definition ln⁡(λ)=y  ⟺  ey=λ\ln(\lambda) = y \iff e^y = \lambda is what makes this rewriting exact.

Problem it solves

Products of probabilities underflow to zero in floating-point for even moderate nn (e.g., 500 Bernoulli trials with p=0.5p = 0.5 gives 2−500≈3×10−1512^{-500} \approx 3 \times 10^{-151}, below float64 minimum). The log definition maps this product to a sum of log-probabilities, which is computationally stable.

How it solves the problem

By definition: ln⁡(p1⋅p2⋯pn)=∑iln⁡pi\ln(p_1 \cdot p_2 \cdots p_n) = \sum_i \ln p_i (the product rule for logs, which follows from the definition). Each ln⁡pi∈(−∞,0]\ln p_i \in (-\infty, 0] for pi∈(0,1]p_i \in (0, 1], so the sum stays in floating-point range. Maximizing the log-likelihood gives the same parameter estimates as maximizing the likelihood, because ln⁡\ln is a monotone increasing function.

Example in a business

A data scientist fits a log-normal pricing model: prices are log-normally distributed, so ln⁡(price)∼N(μ,σ2)\ln(\text{price}) \sim \mathcal{N}(\mu, \sigma^2). They apply the definition directly: ln⁡(price)=y\ln(\text{price}) = y means price =ey= e^y. After fitting μ\mu and σ2\sigma^2 on the log scale (using standard linear regression), they recover price predictions via price^=ey^\hat{\text{price}} = e^{\hat{y}}. The definition is the explicit mapping used at every step.

The formula, piece by piece

Breaking the notation:

  • yy: the logarithm — the answer; it is always an exponent.
  • log⁡a\log_a: "log base aa" — the function that asks: "what power of aa gives this argument?"
  • xx: the argument — must be strictly positive (x>0x > 0).
  • aa: the base — must be positive and ≠1\ne 1 (a=1a = 1 gives 1y=11^y = 1 for all yy, making the inverse undefined).
  •   ⟺  \iff: "if and only if" — the two forms are completely equivalent; each implies the other.
  • ay=xa^y = x: the exponential form.

This is what the logarithm means. Equivalence table (two forms of the same fact):

Logarithmic form Exponential form Plain English
log⁡28=3\log_2 8 = 3 23=82^3 = 8 2 to the 3rd = 8
log⁡101000=3\log_{10} 1000 = 3 103=100010^3 = 1000 10 to the 3rd = 1000
ln⁡e=1\ln e = 1 e1=ee^1 = e e to the 1st = e
log⁡a1=0\log_a 1 = 0 a0=1a^0 = 1 anything to the 0th = 1
ln⁡(1/e)=−1\ln(1/e) = -1 e−1=1/ee^{-1} = 1/e negative exponent = reciprocal

TRAP: log of a sum ≠ sum of logs. log⁡a(x+y)≠log⁡ax+log⁡ay\log_a(x + y) \ne \log_a x + \log_a y. This confusion appears constantly. The product rule log⁡a(xy)=log⁡ax+log⁡ay\log_a(xy) = \log_a x + \log_a y holds (different identity), but the sum rule does not.

The formula in words

"y=log⁡axy = \log_a x means: 'yy is the exponent you put on aa to get xx.' Equivalently: ay=xa^y = x. The logarithm is the inverse of exponentiation with the same base. To evaluate log⁡ax\log_a x: ask 'what power of aa equals xx?' In code: math.log(x, a) returns yy such that a**y == x. In ML: np.log gives ln⁡=log⁡e\ln = \log_e. Domain: argument must be positive. Range: all reals."

Critical Concepts

  1. The logarithm is an exponent: this is not a metaphor. The output of log⁡ax\log_a x is literally the exponent yy such that ay=xa^y = x. Every property of logarithms follows from this.
  2. Domain constraint x>0x > 0: you cannot take a log of zero or a negative number. In ML, log-probabilities are always negative (since 0<p≤10 < p \le 1, ln⁡p≤0\ln p \le 0). Log of zero is −∞-\infty, which triggers numerical issues.
  3. ln⁡\ln is default in ML/stats: unless specified, "log" in mathematical texts means ln⁡\ln (natural log). Python's math.log(x) and np.log(x) both compute ln⁡x\ln x.
  4. Inverse of exponential: log⁡a\log_a and a(⋅)a^{(\cdot)} are inverse functions. Their graphs are reflections across y=xy = x. The cancellation identities alog⁡ax=xa^{\log_a x} = x and log⁡a(ax)=x\log_a(a^x) = x express this directly.
  5. TRAP: log is not linear: log⁡a(x+y)≠log⁡ax+log⁡ay\log_a(x + y) \ne \log_a x + \log_a y.

Only the product decomposes: log⁡a(xy)=log⁡ax+log⁡ay\log_a(xy) = \log_a x + \log_a y. A common error in probability computations.

Step-by-step calculation (tiny example)

Task: evaluate log⁡232\log_2 32 and log⁡100.001\log_{10} 0.001.

Step 1: Rewrite the question using the definition log⁡232=y  ⟺  2y=32\log_2 32 = y \iff 2^y = 32.

Step 2: Solve for yy using known powers 21=22^1 = 2, 22=42^2 = 4, 23=82^3 = 8, 24=162^4 = 16, 25=322^5 = 32. So y=5y = 5.

Step 3: Verify 25=322^5 = 32. Therefore log⁡232=5\log_2 32 = 5.

Step 4: Second example — log⁡100.001\log_{10} 0.001 log⁡100.001=y  ⟺  10y=0.001=10−3\log_{10} 0.001 = y \iff 10^y = 0.001 = 10^{-3}. So y=−3y = -3.

Step 5: Verify 10−3=1/1000=0.00110^{-3} = 1/1000 = 0.001. Therefore log⁡100.001=−3\log_{10} 0.001 = -3.

Code examples

Beginner example (Python)

python
# Logarithm definition: y = log_a(x) iff a^y = x
import math
import numpy as np

# Verify the definition: log_a(x) = y means a^y = x
print("Definition verification: a^(log_a(x)) == x")
test_cases = [
    (2.0, 8.0),   # log_2(8) = 3
    (10.0, 1000.0),   # log_10(1000) = 3
    (10.0, 0.001),   # log_10(0.001) = -3
    (math.e, math.e),   # ln(e) = 1
    (math.e, 1.0),   # ln(1) = 0
    (3.0, 81.0),   # log_3(81) = 4
]
print(f"{'a':>6} {'x':>10} {'log_a(x)':>10} {'a^y':>10} {'verified':>8}")
for a, x in test_cases:
    y = math.log(x, a)
    a_to_y = a ** y
    verified = abs(a_to_y - x) < 1e-9
    print(f"{a:>6.3f} {x:>10.4f} {y:>10.6f} {a_to_y:>10.6f} {str(verified):>8}")

# Special values
print("\nSpecial values:")
for a in [2.0, math.e, 10.0]:
    print(f" log_{a:.4f}(1) = {math.log(1, a):.4f} (a^0 = 1)")
    print(f" log_{a:.4f}(a) = {math.log(a, a):.4f} (a^1 = a)")

# Natural log vs log-2 vs log-10
print("\nThree common bases for x = 100:")
x = 100.0
print(f" ln(100) = {math.log(x):.6f} (base e)")
print(f" log2(100) = {math.log2(x):.6f} (base 2)")
print(f" log10(100) = {math.log10(x):.6f} (base 10)")

# TRAP: log(x + y) != log(x) + log(y)
x_val, y_val = 3.0, 5.0
print(f"\nTRAP: ln({x_val}+{y_val}) = {math.log(x_val + y_val):.6f}")
print(f" ln({x_val})+ln({y_val}) = {math.log(x_val) + math.log(y_val):.6f}")
print(f" These are NOT equal — log of sum ≠ sum of logs")

Beginner example (R)

r
# Logarithm definition in R: y = log_a(x) iff a^y = x
# Verify the definition
test_cases <- list(
  c(a = 2, x = 8),
  c(a = 10, x = 1000),
  c(a = exp(1), x = exp(1)),
  c(a = exp(1), x = 1),
  c(a = 3, x = 81)
)
cat(sprintf("%-6s %-10s %-10s %-10s %s\n", "a", "x", "log_a(x)", "a^y", "verified"))
for (tc in test_cases) {
  a <- tc["a"]; x <- tc["x"]
  y <- log(x, base = a)
  a_y <- a^y
  cat(sprintf("%-6.3f %-10.4f %-10.6f %-10.6f %s\n", a, x, y, a_y, abs(a_y - x) < 1e-9))
}

# Natural log, log2, log10
cat("\nFor x = 100:\n")
cat(sprintf(" log(100) = %.6f (base e)\n", log(100)))
cat(sprintf(" log2(100) = %.6f (base 2)\n", log2(100)))
cat(sprintf(" log10(100) = %.6f (base 10)\n", log10(100)))

# TRAP: log(x + y) ≠ log(x) + log(y)
cat(sprintf("\nTRAP: ln(3+5) = %.6f\n", log(8)))
cat(sprintf(" ln(3)+ln(5) = %.6f — NOT equal\n", log(3) + log(5)))

Professional example (Python)

python
import numpy as np
import pandas as pd
import math   # Scenario: demonstrate the log definition as the backbone of log-likelihood
# and log-scale data transformation in a marketing campaign analysis
np.random.seed(42)
N_SAMPLES = 1000

def log_likelihood_poisson(data: np.ndarray, lam: float) -> float:
    """ Compute Poisson log-likelihood: ln L(lambda) = sum_i [x_i * ln(lambda) - lambda - ln(x_i!)] Applies the definition log_a(x) = y iff a^y = x: ln(lambda^x_i) = x_i * ln(lambda) — the log brings the exponent down. Args: data: Array of non-negative integer observations. lam: Poisson rate parameter (lambda > 0). Returns: Log-likelihood value (always <= 0 for a proper probability model). """
    if lam <= 0:
        raise ValueError("lambda must be positive")
    return float(np.sum(data * np.log(lam) - lam - np.array([math.lgamma(x + 1) for x in data])))

def evaluate_log_scale_transform(values: np.ndarray) -> pd.DataFrame:
    """ Compare raw vs log-transformed values to illustrate log domain properties. Args: values: Array of positive values to transform. Returns: DataFrame comparing raw and log-transformed values. """
    log_vals = np.log(values)
    return pd.DataFrame({ "raw": values.round(2), "ln_x": log_vals.round(4), "exp_back": np.exp(log_vals).round(2),   # recovers original via definition
        "round_trip": np.abs(np.exp(log_vals) - values) < 1e-9, })   # Generate Poisson data with true lambda = 5 (e.g., customer clicks per session)
TRUE_LAMBDA = 5.0
click_data = np.random.poisson(TRUE_LAMBDA, N_SAMPLES)   # Evaluate log-likelihood over a grid of lambda values
lambda_grid = np.linspace(2.0, 10.0, 200)
log_likelihoods = np.array([log_likelihood_poisson(click_data, lam) for lam in lambda_grid])
best_lambda = lambda_grid[np.argmax(log_likelihoods)]   # Log-scale transformation demo on revenue values
revenue_sample = np.random.lognormal(mean=4.0, sigma=1.2, size=8)
transform_df = evaluate_log_scale_transform(revenue_sample)
print("Poisson log-likelihood: ln L(lambda) uses ln by definition log_e(x) = y iff e^y = x")
print("=" * 72)
print(f" True lambda: {TRUE_LAMBDA:.2f}")
print(f" MLE estimate (grid): {best_lambda:.4f}")
print(f" Sample mean (MLE exact): {click_data.mean():.4f}")
print(f" Max log-likelihood: {np.max(log_likelihoods):.4f}")
print()
print("Log-scale transform: y = ln(revenue) i.e. e^y = revenue")
print("-" * 56)
print(transform_df.to_string(index=False))
print(f"\nAll round-trips exact (e^(ln x) = x): {transform_df['round_trip'].all()}")
print(f"\nDomain enforcement: ln(x) requires x > 0")
print(f" Revenue min: {revenue_sample.min():.4f} (all positive, safe for ln)")

Professional example (R)

r
# y = ln(revenue), e^y = revenue (definition of ln)
set.seed(42)
revenue_sample <- runif(20, 100, 10000)
log_revenue <- log(revenue_sample)
round_trip <- exp(log_revenue)
transform_df <- data.frame(revenue = revenue_sample, log_revenue = log_revenue, round_trip = round_trip, match = abs(round_trip - revenue_sample) < 1e-10)
cat("Log-scale: y = ln(revenue), e^y = revenue\n")
print(head(transform_df, 5))
cat(sprintf("\nAll round-trips exact: %s\n", all(transform_df$match)))

Source: 1300 p. 20

#algebra#exponentials-and-logarithms#definition-and-properties

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