Contents
If and , then and
Deep Breakdown
What it tells me (Situation Awareness): When you multiply or divide both sides of an inequality by a negative number, the direction of the inequality reverses. Formally: if and , then and . This is one of the most commonly violated rules in algebraic manipulation, and it is especially easy to overlook in DA/DS when dealing with gradient directions, sign-based loss transformations, and convex/concave function comparisons. Key appearances: (1) optimizing a loss function — minimizing is equivalent to maximizing ; when you write , the flip is implicit; (2) inequality constraints in linear programs — multiplying a constraint by to convert to (standard form) flips the sign and the direction; (3) confidence interval reversal — if you standardize by dividing by a negative quantity, the bounds reverse; (4) gradient sign analysis — if a gradient is negative, increasing a parameter decreases the loss; this sign flip is the inequality flip applied to the direction of change; (5) correlation sign — if , then , and any inequality involving the covariance flips when negated.
Flowchart
Real-world use
Where it is used
Linear programming standard form: optimization problems are often written with constraints. Converting to (standard form) requires multiplying by : becomes . The inequality flips because the multiplier is . Gradient descent direction: if , then increasing (positive step) decreases . This is the flip in action: , meaning the negated gradient points in the direction of steepest ascent.
Problem it solves
Many derivations involve multiplying both sides of an inequality by a negative quantity (a coefficient, a negative correlation, a negated weight). Without the flip rule, sign errors propagate silently, producing incorrect optimization directions, wrong confidence interval bounds, or inverted inequality constraints.
How it solves the problem
Proof: suppose , so . Multiply both sides by : (product of positive and negative is negative). Expanding: , so . For division: and when , so division is just multiplication by , and the same flip applies.
Example in a business
A data scientist is solving a portfolio allocation problem. The constraint is that expected return . To feed this into a standard linear solver that expects constraints, they multiply both sides by : . The inequality flips from to because the multiplier is . This is one of the most routine transformations in constrained optimization.
The formula, piece by piece
Breaking the notation:
- : the starting inequality — is strictly greater than .
- : the negative multiplier (or divisor).
- : the result — after multiplying by the negative , the inequality direction reverses: previously larger is now smaller.
- : same result for division — dividing by also reverses the direction. Why it reverses (intuitive): multiplying by a negative flips the number line.
If is to the right of on the number line, then is to the left of after reflecting about . Comparison of cases:
| Condition | Operation | Inequality direction |
|---|---|---|
| multiply or divide | preserved: | |
| multiply or divide | reversed: | |
| multiply | all become zero (trivial) | |
| divide | undefined |
Non-strict version: if and , then (weak inequality with equality possible). TRAP: only for multiplication/division, not addition/subtraction. Adding or subtracting any real number (positive, negative, or zero) from both sides of an inequality never changes the direction: for any .
The formula in words
"Multiplying or dividing both sides of an inequality by a negative number reverses the direction. and gives . Always check the sign of the multiplier before deciding whether the inequality direction stays or flips. In optimization: negating an objective converts minimization to maximization (and vice versa). In LP: multiply constraint by to get (standard form), flipping direction. In gradient analysis: a negative gradient means the function decreases in the positive direction."
Critical Concepts
- Sign of multiplier determines direction: positive multiplier preserves inequality; negative multiplier reverses it. This is the complete rule. No exceptions (except , where division is undefined and multiplication gives ).
- Minimization–maximization duality: . This implicit inequality flip is used constantly: the cross-entropy loss is minimized by maximizing the log-likelihood (which is cross-entropy). The negative multiplier here is .
- LP standard form conversions: becomes . Both the coefficient vector and the right-hand side change sign. The direction flips from to .
- Gradient descent sign logic: if , the parameter should decrease (negative update). If , it should increase (positive update). The update automatically handles this via the flip rule.
- TRAP: chain of flips: applying the flip rule twice (multiplying by two negatives, i.e., a positive) returns to the original direction.
Track each sign change explicitly to avoid accumulated errors in multi-step derivations.
Step-by-step calculation (tiny example)
Task: convert to a form with isolated.
Step 1: Identify the current state . The coefficient of is .
Step 2: Divide both sides by Dividing by flips the inequality direction. .
Step 3: Simplify .
Step 4: Verify with a specific value Take . Check original: . Take . Check original: , so it is correctly excluded.
Step 5: Contrast with positive coefficient If the problem were : dividing by gives (direction preserved). The difference is purely the sign of the divisor.
Code examples
Beginner example (Python)
# Inequality flip when multiplying/dividing by a negative number
import numpy as np
def multiply_inequality(a: float, b: float, m: float) -> dict:
""" Multiply both sides of a > b by m and check if direction is preserved. Args: a: Left-hand side value (a > b assumed). b: Right-hand side value. m: Multiplier. Returns: Dictionary with original and transformed inequality info. """
assert a > b, "Requires a > b"
am, bm = a * m, b * m
return { "original": f"{a} > {b}", "multiplier": m, "transformed": f"{am:.4f} {'>' if am > bm else '<' if am < bm else '='} {bm:.4f}", "flipped": m < 0, "am_gt_bm": am > bm, } # Demonstrate the rule
print("Inequality flip: a > b and m < 0 → am < bm")
a, b = 5.0, 2.0
cases = [3.0, 1.0, -1.0, -3.0, 0.5, -0.5]
for m in cases:
result = multiply_inequality(a, b, m)
print(f" m={m:5.1f}: {result['original']} → {result['transformed']} " f"(flipped: {result['flipped']})") # Solving -3x > 12
print("\nSolving -3x > 12:")
print(" Divide by -3 (negative) → flip direction: x < 12/(-3) = -4")
x_vals = [-6.0, -5.0, -4.0, -3.0, -2.0]
for x in x_vals:
lhs = -3 * x
in_sol = x < -4
lhs_ok = lhs > 12
print(f" x={x:5.1f}: -3x={lhs:7.1f} satisfies original (-3x>12): {lhs_ok} " f"satisfies solution (x<-4): {in_sol} consistent: {lhs_ok == in_sol}") # Minimization to maximization (the most common flip in ML)
print("\nMin f = Max(-f):")
def f(x: np.ndarray) -> np.ndarray:
"""Quadratic: f(x) = (x-3)^2 + 1."""
return (x - 3) ** 2 + 1
x_grid = np.linspace(0, 6, 100)
f_vals = f(x_grid)
neg_f = -f_vals
min_f_idx = np.argmin(f_vals)
max_neg_f_idx = np.argmax(neg_f)
print(f" argmin f(x): x = {x_grid[min_f_idx]:.4f} (f = {f_vals[min_f_idx]:.4f})")
print(f" argmax (-f(x)): x = {x_grid[max_neg_f_idx]:.4f} (-f = {neg_f[max_neg_f_idx]:.4f})")
print(f" Same location: {abs(x_grid[min_f_idx] - x_grid[max_neg_f_idx]) < 0.1}")Beginner example (R)
# Inequality flip in R: multiply/divide by negative → reverse direction # Demonstrate
cat("Inequality flip: a > b, m < 0 → am < bm\n")
a_val <- 5; b_val <- 2
multipliers <- c(3, 1, -1, -3, 0.5, -0.5)
for (m in multipliers) { am <- a_val * m; bm <- b_val * m
direction <- ifelse(am > bm, ">", ifelse(am < bm, "<", "="))
cat(sprintf(" m=%5.1f: %d > %d → %.2f %s %.2f (flipped: %s)\n", m, a_val, b_val, am, direction, bm, m < 0))
} # Solve -3x > 12
cat("\nSolve -3x > 12: x < -4 (flip on dividing by -3)\n")
for (x in c(-6, -5, -4, -3, -2)) { lhs <- -3 * x
in_sol <- x < -4
cat(sprintf(" x=%2d: -3x=%4d > 12: %s x<-4: %s consistent: %s\n", x, lhs, lhs > 12, in_sol, (lhs > 12) == in_sol))
}Professional example (Python)
import numpy as np
import pandas as pd # Scenario: LP standard form conversion and gradient descent direction analysis
# Demonstrates inequality flip rule in two common DA/DS contexts
np.random.seed(42) # Part 1: LP constraint conversion (>= to <=)
print("LP Standard Form: a^T x >= b → (-a)^T x <= -b (flip when multiplying by -1)")
print("=" * 68)
constraints_ge = [ {"name": "min return", "coeffs": [0.06, 0.04, 0.08], "rhs": 0.05}, {"name": "max risk", "coeffs": [-0.02, -0.03, -0.01], "rhs": -0.025}, {"name": "budget", "coeffs": [1.0, 1.0, 1.0], "rhs": 1.0},
]
rows = []
for c in constraints_ge:
coeffs_neg = [-v for v in c["coeffs"]]
rhs_neg = -c["rhs"]
rows.append({ "constraint": c["name"], "original_form": f"[{', '.join(f'{v:.2f}' for v in c['coeffs'])}]·x >= {c['rhs']:.3f}", "standard_form": f"[{', '.join(f'{v:.2f}' for v in coeffs_neg)}]·x <= {rhs_neg:.3f}", "flip_applied": True, })
lp_df = pd.DataFrame(rows)
print(lp_df.to_string(index=False)) # Part 2: gradient descent sign analysis
print("\n\nGradient descent: update = theta - eta * grad")
print("grad < 0 → theta increases (positive step), grad > 0 → theta decreases (negative step)")
print("-" * 68)
def quadratic_gradient(theta: float, mu: float = 3.0) -> float:
"""Gradient of f(theta) = (theta - mu)^2: f'(theta) = 2*(theta - mu)."""
return 2 * (theta - mu)
LEARNING_RATE = 0.1
MU = 3.0
theta_vals = np.array([0.5, 1.5, 2.5, 3.0, 3.5, 4.5, 5.5])
rows_gd = []
for theta in theta_vals:
grad = quadratic_gradient(theta, MU)
update = -LEARNING_RATE * grad # flip: negative gradient → positive update
theta_new = theta + update
rows_gd.append({ "theta": round(theta, 2), "gradient": round(grad, 4), "update": round(update, 4), "theta_new": round(theta_new, 4), "grad_sign": "negative (move right)" if grad < 0 else "positive (move left)" if grad > 0 else "zero (at min)", })
gd_df = pd.DataFrame(rows_gd)
print(gd_df.to_string(index=False))
print(f"\nConclusion: update = -eta * grad implements the flip rule.")
print(f" When grad < 0: update > 0 → theta increases (moves toward minimum at {MU})")
print(f" When grad > 0: update < 0 → theta decreases (moves toward minimum at {MU})")Professional example (R)
# Gradient descent:
update = -eta * grad (flip when multiplying by negative)
MU <- 3.0
eta <- 0.1
thetas <- c(0, 1, 2, 4, 5)
rows <- lapply(thetas, function(theta) { grad <- 2 * (theta - MU) update <- -eta * grad data.frame(theta = theta, grad = grad, update = update, direction = if (grad < 0) "increase" else "decrease")
})
gd_df <- do.call(rbind, rows)
cat("Gradient descent: update = -eta * grad\n")
print(gd_df)
cat("When grad < 0: update > 0 → theta increases toward minimum.\n")Source: 1300 p. 22