Solving Quadratics Step by Step

by George Beck

This notebook discusses the solutions of quadratic equations in a several different ways. The built-in functions Solve, NSolve, and Factor give three fast  ways to solve a quadratic equation. Their solutions are easy to check.  The defined function WalkSolve solves a quadratic step-by-step by completing the square. We derive the QuadraticFormula and compare it with the Russian version.

Proper formatting of output

From the menu, select Info, Preferences, Action... to produce a big box titled Action Preferences.

Look at the second box within Action Preferences titled Placing Print Output.

Click on the first little button so that there is no check mark for ``Place Print output as it is generated''.

Click on the second little button so that there is a check mark for ``Place each Print line in a separate cell''.

Click on the Apply button at the bottom.

Discussion

Quadratic expressions and equations

This is a quadratic expression. We'll use this example for our discussion, but you can change the numbers to get any example you want.

q = 2 - 4 x + x^2

Setting a quadratic expression equal to zero gives a quadratic equation.

q == 0

Three fast ways to solve quadratic equations

1) Solve

We can find the two solutions with the built-in function Solve. 
The answers are given as rules, and x is not set to any particular value.

solutionrules = Solve[q == 0, x]

Somtimes the answer can be simplified.

solutionrules = Simplify[solutionrules]

If there are square roots you can get decimal approximations by using the function N, which stands for  numeric .

N[solutionrules]

2) NSolve

Use NSolve if you know from the beginning that you want decimals.

NSolve[q == 0, x]

3) Factor

If the solutions are rational you can get them by factoring the expression.

Factor[q]

Here is a quadratic expression that factors over the integers.

Factor[2 - 3 x +  x^2]

Solve[2 - 3 x + x^2 == 0, x]

Checking solutions

The result from Solve is a pair of rules, not a pair of numbers.  We can substitute for x by using slash-dot (/.),  the replacement operator.

Checking that the expression becomes zero

q /. solutionrules

Checking the equation  is satisfied

The result shows that the quadratic equation q equals zero is correct for both solutions.

q == 0 /. solutionrules

Getting the solutions as a list

To get the actual numbers rather than the rules we can substitute out for x.

x /. solutionrules

Again we can get an approximation.

N[%]

Completing the square

WalkSolve finds the solutions one step at a time. Try to follow the algebra.

WalkSolve[q == 0, x]

The quadratic formula

Since we want to have general values for a, b, and c, we remove any values that might have been set for them earlier.

Clear[a, b, c]

This is a general quadratic expression.

Q = a x ^ 2 + b x + c

Since we will want to divide by a, we better assume that it is not zero.  
What if a is zero?

This is the general quadratric equation.

Q == 0

In ordinary mathematical notation there is a plus-or-minus sign in front of the square root and the formula is half as long.

Solve[Q == 0, x]

Let us replace the variable x using these rules.

QuadraticFormula = x /. %

Substitution

We can substitute for a, b, and c without having to give them permanent values. Feel free to use other numbers.

QuadraticFormula /. {a -> 1, b -> 2, c -> 1}

Deriving the quadratic formula one step at a time

Now let's derive the general formula one step at a time. In the first step we have added -c to both sides of the equation. Try to follow each of the other steps.

WalkSolve[Q == 0, x]

The Russian quadratic formula

In Russia they put the general equation into a different form. The coefficient for the quadratic term is 1 instead of a and the linear term is 2 B x instead of b x.

R = x ^ 2 + 2 B x + C;

For the effort of setting up the quadratic in this more special form we get a simpler formula than QuadraticFormula. The algebra also turns out to be simpler.

WalkSolve[R == 0, x]

Implementation

Usage message

WalkSolve::usage = "WalkSolve[q == 0, x] solves for the 
two solutions of the quadratic equation q == 0 in the 
unknown x one step at a time.";

Definitions

Explanation of the program

The variables e1, e2, e3, etc., are equations. We get the next equation by applying an algebraic operation to both sides  of the previous equation. In general these equations will all be different, but it does happen in special cases that there is no change from one to the next. For example, if c = 0, e1 and e2 would be the same. WalkSolveSteps1 eliminates such repetitions in the lines redefining p up to taking the square root; WalkSolveSteps2 eliminates the rest. WalkSolve puts these two pieces together and deals with the case of a double root. 
(Note that f @ g @ h @ x means f[g[h[x]]]. This notation saves a lot of nested brackets.)

WalkSolveSteps1[q_, a_, b_, c_] := Module[
	{e1, e2, e3, e4, e5, e6, p},
	e1 = q == 0;
	e2 = -c + First @ e1 == -c + Last @ e1;
	e3 = First @ e2 / a == Last @ e2 / a;
	e4 = Expand @ First @ e3 == Last @ e3;		
	e5 = b ^ 2 / (4 a ^ 2) + First @ e4 == 
		 b ^ 2 / (4 a ^ 2) + Last @ e4;
	e6 = Factor /@ e5;
	p = If[e1 === e2, {e1}, {e1, e2}];
	p = If[e2 === e3, p, Append[p, e3]];
	p = If[e3 === e4, p, Append[p, e4]];
	p = If[e4 === e5, p, Append[p, e5]];
	p = If[e5 === e6, p, Append[p, e6]];
	Do[Print[ p[[i]] ], {i, Length @ p}];
	e6
]

WalkSolveSteps2[x_, e6_, sign_] := Module[
	{e7, d, e8, e, e9, f, e10, p},
	e7 = PowerExpand @ Sqrt @ First @ e6 == 
	sign PowerExpand @ Sqrt @ Last  @ e6;
	d = Denominator @ First @ e7;
	e8 = d First @ e7 == d Last @ e7;
	e = First @ e8 /. x -> 0;
	e9 = First @ e8 - e == Last @ e8 - e;
	f = First @ e9 /. x-> 1;
	e10 = First @ e9 / f == Last @ e9 / f;
	p = If[e7 === e8, {e7}, {e7, e8}];
	p = If[e8 === e9, p, Append[p, e9]];
	p = If[e9 === e10, p, Append[p, e10]];
	Do[Print[ p[[i]] ], {i, Length @ p}];
]

WalkSolve[q_ == 0, x_] := Module[
	{a, b, c, e6},
	{a, b, c} = Reverse @ CoefficientList[q, x];
	e6 = WalkSolveSteps1[q, a, b, c];
If[
	Last @ e6 === 0, 

(* then *)

	Print["We take the square root."];
	WalkSolveSteps2[x, e6, 1];
	Print["This is a double root."],
	
(* else *)

	Print["First we'll take the positive square root."];
	WalkSolveSteps2[x, e6, 1];
	Print["That's the first solution."];
	Print["Now let's take the negative square root."];
	WalkSolveSteps2[x, e6, -1];
	Print["That's the second solution."];
]
]