I.4 · Mathematical Language
What does it mean to do the same thing to both sides?
An equation is a question about an unknown number, and every step of solving it must leave the set of answers unchanged. We keep a balance, learn the one rule that turns an inequality around, and meet the two steps that quietly change the answers: squaring and dividing by something that can be zero.
A balanced statement:
Start from a statement
A balance beam, drawn schematically. At x equal to 0, the left pan holds 2 and the right pan holds 10. The right pan is lower. The tilt shows which side is larger, not by how much.
A number line from minus 11 to 11 with the trial value x at 0. The statement 3 x plus 2 equals x plus 10 is true when x equals 4; those values are marked on the line.
- trial value of x
- 0
- left side at this x
- 2
- right side at this x
- 10
- left minus right (what tilts the beam)
- −8
- is "3x + 2 = x + 10" true at this x?
- false
- solution set of this statement
- {4}
The beam tilts toward the larger side. Left minus right is 0 exactly at a solution of an equation.
At x = 0 the left side is 2 and the right side is 10: the right pan is lower, so x = 0 is not a solution. The statement is true exactly when x = 4.
The history: every step done to both sides
The starting statement. It is true exactly when x = 4. Each operation is applied to both sides, and the set of solutions never changes.
from −12 to 12, up to 2 decimal places
from −10 to 10, up to 2 decimal places
Each operation is applied to the latest statement. Selecting an earlier step in the history only shows it; nothing is undone.
Try it before reading on. Start with and subtract from both sides, then subtract , then divide by . After each step, drag the trial value of to and watch the beam: it is level at the same value every time. Then pick the last statement, , divide by and watch the relation turn around. Finally try to multiply by and read why the stage refuses. By the end of the chapter you will know what a solution set is, why a balanced step keeps it, the one operation that changes an inequality, and the two familiar steps that can change an equation’s answers without warning.
Intuition: a question and a scale
A written equation looks like a fact. It is really a question. When you read you are asked: for which numbers are the two sides equal? For both sides are . For they are and . The unknown is a placeholder, and the equation picks out the numbers that fit.
A pair of kitchen scales is the right picture. The two pans hold the two sides. If they balance, the sides are equal, and whatever you do to one pan you must do to the other if you want them to keep balancing: take a kilogram off both, double both, halve both. The solving procedure is nothing else. Each step produces a new statement with the same answers, only simpler, until the unknown stands alone and the answer can be read off.
Two things can go wrong, and both are the subject of this chapter. Some steps do not keep the answers: multiplying by destroys them, and squaring or dividing by an expression that can be changes them. And the picture has to be extended to inequalities, where “the pan that is lower” is a statement about order and one operation, multiplying by a negative number, turns the order around.
This chapter prepares the next one, Functions as input, transformation and output, where the same letter stops being an unknown to be found and becomes an input that varies. It uses the squares and roots of the first chapter and the number line of the second.
Definition: expressions, equations, inequalities and their solutions
Expression. An expression is a recipe for a number, built from numbers, letters and the operations of arithmetic: , , . It has no "" and is not true or false. It has a value once its letters have values.
Variable, parameter, unknown. A letter stands for a number, and the word used says what the letter is doing. An unknown is a letter whose value we are trying to find ( in ). A variable is a letter that is allowed to take many values, and we study what happens as it does ( in ). A parameter is a letter that is fixed for a given problem but could have been another number ( in ). The same symbol can be any of them, depending on the question.
Equation. An equation states that two expressions have the same value: . It is a condition on . It is true for some values of , false for others.
Inequality. Replace "" by , , or . The statement is again a condition on .
Solution set. The solution set of a statement is the set of all numbers that make it true. Two statements are equivalent when they have the same solution set. Solving means replacing a statement by equivalent ones until the answer is visible.
Identity. An equation that is true for every , such as , is an identity. An equation that is true for no , such as , is a contradiction. Everything else is a conditional equation: it is true for some and false for others.
Balanced operation. An operation applied to both sides of a statement is balanced when the new statement is equivalent to the old. The balanced operations for a linear statement are:
- add the same number, or the same multiple of , to both sides (subtracting is adding a negative number);
- multiply both sides by a number , or divide both sides by .
Each is reversible: adding is undone by adding , and multiplying by is undone by dividing by . That is exactly why it preserves the solution set. If a step turns into and the inverse step turns back into , then every solution of is a solution of and vice versa. Multiplying by has no inverse, and the stage refuses it.
Keeping the balance
A linear equation has a solution set of exactly one of three kinds. Move the terms to the left and the constants to the right, which are two balanced steps. What remains is
Let and . Then:
| value of | the equation | solution set |
|---|---|---|
| divide by : | exactly one number | |
| , | , which is false | no solution |
| , | , which is true | every |
The stage follows this: the beam, the history and the inspector are all computed from the same statement. The beam shows in the left pan and in the right pan at the trial value of . The pan with the larger value is lower, and the beam is exactly level only when the two sides are equal, that is, at a solution of an equation. The amount of tilt is schematic (it grows with the difference but is capped so that the picture stays on the page); the inspector shows the true numbers , and .
Look at the presets. For the terms cancel and the history ends with the false statement ; the solution set is empty, and the verdict is marked as a caution. For they cancel to the true and every works.
The history is a record. Selecting an earlier step with the stepper or the slider shows that statement; it never undoes anything, and the solution set stays the same at every step. You can remove the last step explicitly with its own button, which is a different action.
Why multiplying by is refused
Start from and multiply both sides by . The result is , which is true for every . The original had one solution and the new statement has all of them. Since no number turns back into , the step cannot be undone. A step that changes the solution set is not balanced, and the stage shows its reason instead of accepting it. Dividing by is refused for the plain reason that division by is undefined.
Inequalities and the order-reversing rule
An inequality such as is solved by the same balanced steps, with its relation carried along. Adding a number to both sides keeps the relation. Multiplying by a positive keeps it. The one new fact is this.
If and , then .
Proof. Since , the number is positive. A negative number times a positive number is negative, so , that is , that is .
So multiplying or dividing by a negative number reverses the relation: becomes , and becomes . Geometrically, multiplying by reflects the number line through , which swaps left and right, so what was to the left is now to the right; multiplying by reflects and then stretches by .
Multiply an inequality by : keep the order or reverse it
Try a pair and a multiplier
Two number lines. On the upper line p is at 2 and q is at 5, so 2 is less than 5. On the lower line, after multiplying by minus 2, kp is at minus 4 and kq is at minus 10, so minus 4 is greater than minus 10.
The products on a wider line. kp is at minus 4 and kq is at minus 10.
- first number
- 2
- second number
- 5
- multiplier
- −2
- first number times k
- −4
- second number times k
- −10
- the order before
- 2 < 5
- the true order after
- −4 > −10
- does the old relation still hold?
- no
Multiplying by a negative k reflects the line through 0, so the numbers swap sides.
k = −2 is negative, so the order is REVERSED: "2 < 5" becomes "−4 > −10". Counterexample: if you kept the old sign you would write "−4 < −10", and that is false for these numbers. Multiplying by a negative number reflects the line through 0 (and stretches it by |k|), which swaps left and right.
from −6 to 6, up to 2 decimal places
from −6 to 6, up to 2 decimal places
from −3 to 3, up to 2 decimal places
The stage states the counterexample in numbers. With , and , the true order is , and the products are and . If you forgot to reverse and wrote , you would have written a false statement. The true one is . The multiplier is rejected for a different reason: and are both , so the strict inequality becomes the false , or loses its meaning altogether, and nothing can be divided back.
The solution set of an inequality is an interval, with an exact endpoint and an end that is open or closed. For the steps give , then : the set , and belongs to it because the relation allows equality. For the steps give , then dividing by (reversing) : the set , with excluded. A square bracket or a filled dot means included; a round bracket or an open dot means excluded.
Squaring is not a balanced step
Squaring both sides is tempting: it removes a square root. But the step only goes one way. The squared equation is also true when , so the new statement can have more solutions than the old. The extra ones are called extraneous roots.
Take the family with whole numbers . The square root sign means the non-negative root, so a solution must make the right side non-negative as well. Write for the right side. Then , and squaring gives
So , which is the quadratic with discriminant . The number is always odd.
A candidate solves the original equation exactly when its right side is not negative. If , the number solves instead: the other sign of the root. Because the two values of add up to , the larger one is at least , so at least one candidate is always valid whenever there are candidates. Whether the second is valid depends on the sign of its .
Squaring can invent roots:
Try an equation
A coordinate plane. The solid curve is y equals the square root of x plus 2, the dashed curve is y equals minus that square root, and the straight line is y equals x. Root 1 is at x equal to minus 1, on the lower, dashed branch: extraneous. Root 2 is at x equal to 2, on the upper, solid branch: valid.
- shift under the root
- 2
- shift of the line
- 0
- discriminant 4p − 4q + 1 of the squared equation
- 9
- root 1 of the squared equation
- −1
- root 1 in the ORIGINAL equation
- extraneous
- root 2 of the squared equation
- 2
- root 2 in the ORIGINAL equation
- valid
= exact · ≈ rounded · a root is valid only if the right-hand side x + q is not negative
Root 1, x = −1: the right-hand side x equals −1, which is negative, and a square root is never negative. This x solves −√(x + 2) = x instead. Extraneous. Root 2, x = 2: the right-hand side x equals 2, which is not negative, and the radicand x + 2 equals 4 = 2², so √4 = 2. Valid. Squaring produced 2 candidates but only 1 solves the original equation.
from −6 to 6, whole numbers only
from −6 to 6, whole numbers only
The preset , is . Squaring gives , so and . The candidates are and . Substitute into the original equation: for , and the right side is , so it is valid. For , but the right side is : extraneous. It is a solution of instead.
The preset , has the irrational candidates . The sign of is decided exactly (it is negative because ), not by looking at its decimal . The stage also shows , where : there is no real candidate and squaring cannot create any.
The only reliable test of a candidate is to put it back into the original equation.
The honest scope of this family
Squaring is one of several steps that can add roots. Multiplying both sides by an expression that can be does it too. This chapter treats one family exactly, so that the claim “a candidate is valid exactly when ” can be checked on every case. Other equations with radicals, and equations with fractions, need the same discipline: find the candidates by whatever steps you like, then check them in the original.
Dividing by something that can be zero
The opposite danger is losing a root. Consider . A tempting step is to divide both sides by , which leaves . But the division is allowed only where , that is for . At both sides equal , so is a solution, and the division threw it away.
The safe way is to move everything to one side and factor:
A product is exactly when one of its factors is , so both roots appear. In general is equivalent to .
Dividing by a factor that can be zero:
Try an equation
A coordinate plane with a parabola, the left side, and a straight line, the right side. They cross where the equation is true, at x equal to 2 and 3. The crossing at x equal to 2 is the one that dividing by the factor throws away.
- the zero of the factor
- 2
- the number on the right
- 3
- all solutions
- {2, 3}
- what the division concludes
- x = 3
- the solution the division loses
- x = 2
- left side at x = c
- 0
- right side at x = c
- 0
x(x − 2) = 3(x − 2): both sides are equal at every solution
x(x − 2) = 3(x − 2) has two solutions, {2, 3}. Dividing both sides by (x − 2) is allowed only where x − 2 is not 0, that is for x other than 2. It leaves x = 3 and silently throws away x = 2, where both sides equal 0 (0 = 0). Move everything to one side and factor instead.
from −6 to 6, whole numbers only
from −6 to 6, whole numbers only
When the equation is with the single root . Dividing gives : nothing is lost as a value, but the division was still not justified. The stage keeps both cases apart.
The same lesson applies to simplifying a fraction such as : the two sides agree for every , but the left side is undefined at . A simplification that is valid only where a divisor is not carries that restriction with it. The restriction on is called a domain restriction.
Expanding brackets: identities and slips
The distributive law says that multiplication spreads over addition: for every . It is an identity. Written as an equation , its solution set is every .
The most common slip multiplies only the first term: . The stage compares the two. Write the equation as a pair of lines and . They have the same slope , so they are parallel. They coincide when the constants agree, , which happens exactly when , that is or . Otherwise they are a constant distance apart, and the slip’s equation is a contradiction: true for no . A single numerical check at one already catches it.
Expression, equation, identity:
Try a bracket
A coordinate plane with two straight lines: y equals 2x + 6, the bracket as written, and y equals 2x + 6, its expansion. The two lines coincide: they are the same function of x. At x equal to 2 the heights are 10 and 10.
- outer factor
- 2
- coefficient of x inside
- 1
- constant inside
- 3
- value of x
- 2
- the bracket at this x
- 5
- the product, bracket first
- 10
- every term multiplied
- 10
- product minus expansion
- 0
- what kind of statement is the equation?
- identity
The solid line is the bracket as written, the dashed line is the expansion. The equation is an identity when the lines coincide.
At x = 2 the bracket gives 10 and the expansion gives 10. They agree, and not by luck: both simplify to 2x + 6, so the equation 2x + 6 = 2x + 6 is true for every x. It is an identity: the distributive law.
from −3 to 3, whole numbers only
from −3 to 3, whole numbers only
from −5 to 5, whole numbers only
from −6 to 6, up to 2 decimal places
This is the difference between the words in the definition. The bracket is an expression. Setting it equal to its correct expansion makes an identity, true for every . Setting it equal to the slip makes a contradiction, true for no (except in the harmless cases or , where the slip happens to be right). An equation like is conditional: true only at .
Reading is a first look at the next chapter: the same expression , but now is an input, and and are parameters that define the rule.
Worked examples
Solving a linear equation is three moves in a fixed order, and it pays to see them as steps:
- Collect the terms on one side by adding the opposite of the unwanted term to both sides.
- Collect the constants on the other side the same way.
- Divide by the number in front of (reversing an inequality if it is negative) and then check in the original statement.
Step through five cases. The first is . The second has a solution that is not a whole number. The third is the inequality , where the last step reverses the relation. The fourth is with its extraneous root. The last is the division that loses a root.
Worked examples: solve, then check
Choose a problem
The starting statement. It is true exactly when x = 4. Each operation is applied to both sides, and the set of solutions never changes.
Executable reference code
Run the Python examples below to follow the calculations step by step. First the solver: a function that returns one of exactly three answers, the inequality version with its reversal, and the case of multiplying by .
from fractions import Fraction
def solve_linear(a1, b1, a2, b2):
"""Solve a1*x + b1 = a2*x + b2 exactly. The answer is one of exactly three things."""
m = a1 - a2 # what is left in front of x after moving the x-terms to the left
c = b2 - b1 # what is left on the right after moving the constants
if m == 0: # the equation reads 0 = c and does not involve x at all
return ("all",) if c == 0 else ("none",)
return ("point", Fraction(c) / m) # Fraction keeps integers and decimals-from-strings exact
def solve_inequality(a1, b1, rel, a2, b2):
"""Solve a1*x + b1 (rel) a2*x + b2 for rel in '<', '<=', '>', '>='. Dividing by a negative m reverses the relation."""
flipped = {"<": ">", "<=": ">=", ">": "<", ">=": "<="}
m, c = a1 - a2, b2 - b1
if m == 0: # 0 (rel) c: true for every x or for none
holds = {"<": 0 < c, "<=": 0 <= c, ">": 0 > c, ">=": 0 >= c}[rel]
return ("all",) if holds else ("none",)
if m < 0: # dividing both sides by a negative number reverses the order
rel = flipped[rel]
return ("x", rel, Fraction(c) / m)
# 3x + 2 = x + 10 -> 2x = 8 -> x = 4
print(solve_linear(3, 2, 1, 10)) # ('point', Fraction(4, 1))
print(solve_linear(2, 3, 2, 7)) # ('none',) : 0 = 4
print(solve_linear(2, 3, 2, 3)) # ('all',) : 0 = 0
# the same operation on both sides keeps the solution: subtract x, subtract 2, divide by 2 (each step is reversible)
step1 = (3 - 1, 2, 0, 10) # 2x + 2 = 10
step2 = (2, 0, 0, 8) # 2x = 8
step3 = (1, 0, 0, 4) # x = 4
history_agrees = all(solve_linear(*s) == solve_linear(3, 2, 1, 10) for s in (step1, step2, step3))
print(history_agrees) # True
# multiplying both sides by 0 is the one operation that is NOT allowed: 0 = 0 holds for every x, but x = 4 was the only solution
times_zero = solve_linear(0 * 3, 0 * 2, 0 * 1, 0 * 10) # ('all',)
print(times_zero, times_zero == solve_linear(3, 2, 1, 10)) # ('all',) False
# 4 - 2x < x + 10 -> -3x < 6 -> dividing by -3 reverses the order: x > -2
print(solve_inequality(-2, 4, "<", 1, 10)) # ('x', '>', Fraction(-2, 1))
wrong_if_not_reversed = ("x", "<", Fraction(-2)) # what forgetting the reversal would claim
test_point = Fraction(-5) # satisfies the WRONG answer (-5 < -2) ...
original_holds_at_test_point = (-2 * test_point + 4) < (1 * test_point + 10) # 14 < 5 is False
print(original_holds_at_test_point) # False: ... but not the original inequality
# exactness: the same equation 0.1x + 0.2 = 0.3 solved with floats and with Fractions built from strings
float_x = (0.3 - 0.2) / 0.1 # 0.9999999999999998
exact_x = solve_linear(Fraction("0.1"), Fraction("0.2"), Fraction(0), Fraction("0.3"))[1] # Fraction(1, 1)
print(float_x, exact_x, float_x == 1, exact_x == 1) # 0.9999999999999998 1 False True
# a coefficient that should cancel to exactly 0 may not, in floats: 0.1 + 0.2 - 0.3 is 2**-54, not 0
m_float = (0.1 + 0.2) - 0.3
print(m_float, m_float == 2.0**-54, (2 - 1) / m_float) # 5.551115123125783e-17 True 1.8014398509481984e+16 : "no solution" became a huge x
m_exact = (Fraction("0.1") + Fraction("0.2")) - Fraction("0.3")
print(m_exact, solve_linear(Fraction("0.1") + Fraction("0.2"), 1, Fraction("0.3"), 2)) # 0 ('none',)Then the extraneous-root check, with the substitution test, an exact test with Fraction, and the division fallacy.
import math
from fractions import Fraction
def squared_roots(p, q):
"""Roots of the SQUARED equation x + p = (x + q)**2, i.e. x**2 + (2q - 1)x + (q**2 - p) = 0, as floats (None when there are none)."""
discriminant = 4 * p - 4 * q + 1
if discriminant < 0:
return None
root = math.sqrt(discriminant)
return sorted([(1 - 2 * q - root) / 2, (1 - 2 * q + root) / 2])
def classify(p, q, x):
"""Substitute a candidate into the ORIGINAL equation sqrt(x + p) = x + q. Squaring cannot be trusted; substitution can."""
if x + p < 0:
return "outside the domain" # sqrt(x + p) is not defined for x < -p
return "valid" if math.isclose(math.sqrt(x + p), x + q, abs_tol=1e-12) else "extraneous"
def exact_check(p, q, x):
"""The same test in exact arithmetic for a Fraction x: sqrt(x + p) is a Fraction only if numerator and denominator are perfect squares."""
r = x + p
if r < 0:
return False
n, d = math.isqrt(r.numerator), math.isqrt(r.denominator)
return n * n == r.numerator and d * d == r.denominator and Fraction(n, d) == x + q
# p = 2, q = 0: sqrt(x + 2) = x -> x + 2 = x**2 -> x = -1 or x = 2
roots = squared_roots(2, 0) # [-1.0, 2.0]
verdicts = [classify(2, 0, x) for x in roots] # ['extraneous', 'valid']
print(roots, verdicts)
print(math.sqrt(-1 + 2), "!=", -1) # 1.0 != -1 : the root -1 satisfies -sqrt(x + 2) = x, the other sign
print([exact_check(2, 0, Fraction(x)) for x in (-1, 2)]) # [False, True]
# p = 1, q = 0: sqrt(x + 1) = x has the irrational candidates (1 +- sqrt(5))/2
golden, conjugate = squared_roots(1, 0)[1], squared_roots(1, 0)[0]
print(classify(1, 0, golden), classify(1, 0, conjugate)) # valid extraneous
print(golden, conjugate) # 1.618033988749895 -0.6180339887498949
print(math.sqrt(conjugate + 1), -conjugate) # both are 0.618... (equal up to rounding): the conjugate solves -sqrt(x + 1) = x
print(squared_roots(0, 1)) # None : sqrt(x) = x + 1 has no candidates at all (the discriminant is -3)
# The division fallacy: x(x - 2) = 3(x - 2). Dividing by (x - 2) gives x = 3 and loses x = 2, where both sides are 0.
def both_sides(x, c=2, m=3):
return x * (x - c), m * (x - c)
solutions = [x for x in range(-10, 11) if both_sides(x)[0] == both_sides(x)[1]] # a scan, nothing divided
print(solutions) # [2, 3]
print(both_sides(2)) # (0, 0) : dividing by (x - 2) is dividing by zero at x = 2Finally the two machine-learning situations of this chapter: undoing a standardisation, and a learning rate as a factor in an inequality.
from fractions import Fraction
# Standardising a feature is an affine map z = (x - mu) / sigma. Undoing it is solving z = (x - mu) / sigma for x:
# multiply both sides by sigma (not 0), then add mu: both are balanced, reversible operations.
def standardise(x, mu, sigma):
return (x - mu) / sigma
def unstandardise(z, mu, sigma):
return z * sigma + mu
mu, sigma = Fraction(50), Fraction(8)
values = [Fraction(v) for v in (42, 50, 66, 53)]
z = [standardise(v, mu, sigma) for v in values] # [-1, 0, 2, 3/8]
back = [unstandardise(t, mu, sigma) for t in z]
print([str(t) for t in z]) # ['-1', '0', '2', '3/8']
print(back == values) # True: the two maps undo each other exactly (with floats this can fail in the last digit)
# sigma = 0 is the case "multiply by 0" in disguise: a constant feature cannot be standardised, and the inverse does not exist
constant_feature = [Fraction(7)] * 4
sigma_zero = Fraction(0)
try:
standardise(constant_feature[0], Fraction(7), sigma_zero)
except ZeroDivisionError as error:
print("sigma = 0:", type(error).__name__) # ZeroDivisionError: nothing can be divided by 0
# A learning rate is a scale factor in an inequality. Gradient descent on f(w) = (w - c)**2 steps w <- w - eta * 2(w - c),
# so the distance to the minimiser is multiplied by (1 - 2*eta) at every step.
def step(w, c, eta):
return w - eta * 2 * (w - c)
def contracts(eta):
"""|1 - 2*eta| < 1 <=> -1 < 1 - 2*eta < 1 <=> (subtract 1) -2 < -2*eta < 0 <=> (divide by -2 and REVERSE) 1 > eta > 0."""
return 0 < eta < 1
c = Fraction(3)
for eta in (Fraction(1, 4), Fraction(1, 2), Fraction(3, 4), Fraction(-1, 10), Fraction(11, 10)):
w = Fraction(0)
for _ in range(3):
w = step(w, c, eta)
print(str(eta), str(abs(w - c)), contracts(eta))
# eta = 1/4 -> 3/8 (|1 - 1/2|**3 * 3), contracts
# eta = 1/2 -> 0 (a step of 1/2 lands on the minimiser), contracts
# eta = 3/4 -> 3/8 (|1 - 3/2|**3 * 3 = 3/8), contracts
# eta = -1/10 -> 648/125 = 5.184 : the sign of eta is wrong, every step moves AWAY from the minimiser (factor 6/5)
# eta = 11/10 -> 648/125 = 5.184 : too large, each step overshoots by more than it gained (factor -6/5)Two observations about the first file. The inputs are turned into Fractions so that the answer is exact; Fraction("0.1") is one tenth, while the float 0.1 is a binary approximation of it. And the function returns a tuple whose first entry is one of "point", "none" or "all": the three kinds of solution set, made explicit instead of hidden in a float.
Explore: change the parameters
These questions have definite answers; check them against the stages.
- On the balance stage, choose . Which trial values of make the beam tilt toward the left pan, and does the verdict say the statement is true there?
- On the balance stage, start from and multiply both sides by before doing anything else. Is the beam level at the same ? Which trial value is it level at in the new statement?
- On the balance stage, try to multiply by . What does the stage say, and where is that fact in the definition?
- On the reversal stage, find all pairs with and for which the products and are both positive.
- On the extraneous stage, find every for which gives an extraneous root. (Hint: it depends on whether is greater than .)
- On the extraneous stage, find a pair with that has no real candidate, and one with where both roots are valid.
- On the division stage, which make the line tangent to the parabola?
Common mistakes
Numerical considerations
The mathematics above is exact. A program that solves equations with doubles is not, and two problems appear even for tiny, harmless-looking equations.
Equality of the answer. Solve by hand: subtract , divide by , and the answer is exactly . In doubles, (0.3 - 0.2) / 0.1 is 0.9999999999999998, and == 1 is False. The table solves several equations exactly with the model’s rational arithmetic, next to the double a program holds. A row marked “no” is a case where the program’s answer is a different number from the true one.
| equation | Python | exact x | double (what the program holds) | agree? |
|---|---|---|---|---|
| 3*x + 2 = 1*x + 10 | (10 - 2) / (3 - 1) | 4 | 4 | yes |
| 0.1*x + 0.2 = 0.3 | (0.3 - 0.2) / (0.1 - 0) | 1 | 0.9999999999999998 | ⚠ no |
| 0.1*x + 0.7 = 0.8 | (0.8 - 0.7) / (0.1 - 0) | 1 | 1.0000000000000009 | ⚠ no |
| 0.3*x + 0.1 = 0.7 | (0.7 - 0.1) / (0.3 - 0) | 2 | 2 | yes |
| 0.1*x = 0.3 | (0.3 - 0) / (0.1 - 0) | 3 | 2.9999999999999996 | ⚠ no |
| 0.7*x + 0.1 = 0.8 | (0.8 - 0.1) / (0.7 - 0) | 1 | 1.0000000000000002 | ⚠ no |
| 1.1*x = 3.3 | (3.3 - 0) / (1.1 - 0) | 3 | 2.9999999999999996 | ⚠ no |
A coefficient that should vanish. The three-way answer depends on whether is exactly . In doubles, (0.1 + 0.2) - 0.3 is not but . The equation has no solution (the terms cancel to and leave ), but computed in floats the program divides by and reports with full confidence. The reference file above shows both calculations: the float one and the exact one that returns none.
Substitution with a tolerance. The extraneous-root test in the reference file compares math.sqrt(x + p) with x + q using math.isclose. That is adequate for the whole-number parameters of this family, where a valid root has a right side of at least and an invalid one has a negative right side of at least about in size. For other equations the tolerance decides the verdict, and a tolerance that is too wide accepts a false root while one that is too narrow rejects a true one. The exact test (a Fraction whose square root is itself a Fraction) cannot be fooled but works only when the root is rational.
Connections to engineering and machine learning
- Undoing a transformation. Standardising a feature, , is an affine map, and getting back to the original scale is solving that equation for : multiply by (not ) and add . A feature with is the “multiply by ” case in disguise: the map cannot be undone, and a constant column cannot be standardised.
- Learning rates are factors in an inequality. Gradient descent on updates , so the distance to the minimiser is multiplied by at every step. The distance shrinks when . Written as and solved with the steps of this chapter, subtracting gives , and dividing by reverses both inequalities: . The condition matters: a negative rate moves away from the minimum. The reference file runs three steps for several rates.
- One-dimensional least squares. Fitting a single weight to gives , valid only for . When the equation says : no solution if , every if . The three cases of this chapter are the three behaviours of the linear system in one unknown, and they return in higher dimensions.
- Thresholds on a loss. A stopping rule such as “stop when the loss is below ” is an inequality in the parameters. Rearranging it by hand needs the same reversal rule whenever a negative coefficient is involved.
- Domain guards in code. The division fallacy is the source of many runtime errors: a formula simplified by hand is fine for and a
ZeroDivisionErrorat . Write the restriction down with the formula. - Looking ahead. In Functions the expression becomes a rule with a domain, and an equation asks for the inputs that produce a given output.
Exercises
Answer each question and press Check. A wrong answer tells you which mistake it looks like. After one attempt you may open a worked solution.
Summary and checkpoints
- An equation or inequality is a condition on an unknown; its solution set is the set of numbers that satisfy it. A linear equation has exactly one solution, none, or every number.
- A balanced step (add the same thing to both sides, multiply or divide both sides by a non-zero number) is reversible, so it keeps the solution set. Multiplying by is not reversible and is refused.
- Multiplying or dividing by a negative number reverses an inequality, because it reflects the line through . Test a value to catch a missed reversal.
- Squaring is not a balanced step: it can add roots (extraneous roots). Substitute each candidate into the original equation.
- Dividing by an expression that can be can lose a root. Move everything to one side and factor instead.
- is an identity; the slip gives a contradiction unless or .
- In code: keep coefficients exact, never compare a float answer with
==, and test whether a coefficient that should cancel is exactly .
Checkpoints. You are ready to move on when you can, without looking:
- Solve and say what the beam does at the solution.
- Say what the solution set of is, and why.
- Divide by and explain, with a number, why the relation turns around.
- Name the extraneous root of and the reason it fails in the original equation.
- Say which solution of is lost by dividing by .