# Defining a function that completes the square given a quadratic polynomial expression

How can I write a function that would complete the square in a quadratic polynomial expression such that, for example,

CompleteTheSquare[5 x^2 + 27 x - 5, x]


evaluates to

-(829/20) + 5 (27/10 + x)^2

-
I already have a solution that I want to discuss and maybe improve. I will post it in 8+ hours as soon as I am allowed to. – Sunday Apr 9 '13 at 15:46
This is a special case (and therefore a duplicate) of this one. I am not voting to close right now given your desire to post and discuss your solution. – Leonid Shifrin Apr 9 '13 at 16:02
There is such a function in the "Presentations" package of David Park home.comcast.net/~djmpark/index.html – Alexei Boulbitch May 18 '15 at 12:33

I was waiting for OP to post his answer before posting mine. In any event, here's a general routine for performing polynomial depression (where completing the square corresponds to the quadratic case):

depress[poly_] := depress[poly, First@Variables[poly]]

depress[poly_, x_] /; PolynomialQ[poly, x] := Module[{n = Exponent[poly, x], x0},
x0 = -Coefficient[poly, x, n - 1]/(n Coefficient[poly, x, n]);
Normal[Series[poly, {x, x0, n}]]]


Examples:

depress[5 x^2 + 27 x - 5]
-(829/20) + 5 (27/10 + x)^2

depress[2 x^3 - 7 x^2 + 19 x - 4]
319/27 + 65/6 (-(7/6) + x) + 2 (-(7/6) + x)^3

-
Nice generalization. +1 – Mr.Wizard Apr 10 '13 at 11:13
It looks like there will be a lot of polynomials out there requiring meds after your pogrom of depression. (+1) – rcollyer Apr 10 '13 at 12:59
@rcollyer: the mathematicians talk about polynomial "lifting" too; I suppose that's the proper thing to do afterwards... – J. M. Apr 10 '13 at 13:08
First you depress them, then you lift them. Sounds like a cycle of abuse to me. When will the senseless polynomial abuse stop?!? Before you know it, there will be free radicals roaming about trying to cause havoc! – rcollyer Apr 10 '13 at 13:16
cts[pol_,var_]:= Module[{a, b, c},
b (a + var)^2 + c /.
Solve[ForAll[var, pol == b (a + var)^2 + c], {a, b, c}]]

cts[5 x^2 + 27 x - 5, x]
(*
{-(829/20) + 5 (27/10 + x)^2}
*)


and the general solution is of course:

cts[a x^2 + b x + c, x]
(*
{(-b^2 + 4 a c)/(4 a) + a (b/(2 a) + x)^2}
*)

-

You can work out the general form of the coefficients but here's one implementation:

completeTheSquare[p_, x_] :=
Module[{a, b, c}, (a ( x + b)^2 + c) /.
CoefficientList[Expand[a ( x + b)^2 + c], x] ==
CoefficientList[p, x]], {a, b, c}]]

completeTheSquare[12 x^2 + 2 x - 7, x]
(*out*){-(85/12) + 12 (1/12 + x)^2}

completeTheSquare[5 x^2 + 27 x - 5, x]
(*out*){-(829/20) + 5 (27/10 + x)^2}

-

Here's my take:

CompleteTheSquare[a_. x_^2 + b_ x_ + c_, x_] :=
a (x - (-b/(2 a)))^2 + (c - b^2/(4 a))


Note the dot after the a_, for cases where a is 1.

CompleteTheSquare[5 x^2 + 27 x - 5, x]


gives

-(829/20) + 5 (27/10 + x)^2

-

Strictly speaking, the following doesn't reveal how to code completing the square. But if you have David Park's Presentations add-on (see http://home.comcast.net/~djmpark/DrawGraphicsPage.html), then you can do:

   <<Presentations

CompleteTheSquare[2 x^2 - 3 x + 5, x]
(*  31/8 + 2*(-3/4 + x)^2  *)


And if you look into the Manipulations package within Presentations, you'll find the code for Park's CompleteTheSquare.

-

this is my own solution:

CompleteTheSquare[e_, x_] := Module[{a, b, c, B, C},
a (x + B)^2 + C //. {
a -> Coefficient[e, x, 2],
b -> Coefficient[e, x, 1],
c -> Coefficient[e, x, 0],
B -> b/(2 a),
C -> c - b^2/(4 a)
}
];

-
I think it is quite readable. Is there any guru around who could elaborate a bit about the different solutions and whether they are equivalent or where they differ? – Sunday Apr 10 '13 at 8:51
You might want to look into CoefficientList[], which gives all the coefficients in one blow. – J. M. Apr 10 '13 at 11:04

Storing the general solution as a rule and applying it to expression. (Rule edited after consultation with @Mr.Wizard.)

complete = a_. x_Symbol^2 + b_. x_Symbol + c_. :>
a (x + b/(2 a))^2 - b^2/(4 a) + c;

Sqrt[5]^2 u^2 + 27 u - 5 /. complete

(* -(829/20) + 5 (27/10 + u)^2 *)

-
Which doesn't work always ... – BoLe Apr 10 '13 at 9:53
Edited, with a optional pattern _. that can be missing from the expression, via @RunnyKine. – BoLe Apr 10 '13 at 10:00
I believe a, b, and c should be localized (:>). Also, shouldn't x be a parameter? Perhaps something like this?: complete = a_. #^2 + b_. # + c_. :> a (# + b/(2 a))^2 - b^2/(4 a) + c &; then: 5 x^2 + 27 x - 5 /. complete[x] – Mr.Wizard Apr 10 '13 at 11:12
I agree about x -- is it just for the case of an arbitrarily named variable? I don't really know about the rule; I can understand -> vs. :> in a case like {{1, 2}, {1, 3}, {1, 5}} /. {i_, j_} -> {i, RandomReal[]} but what's the difference here? – BoLe Apr 10 '13 at 11:57
Rule does not localize symbols while RuleDelayed does. Using your code as written start with a = b = c = "Fail"; and you will get (3 "Fail")/4 + "Fail" (1/2 + x)^2; change only -> to :> and you get -(829/20) + 5 (27/10 + x)^2 – Mr.Wizard Apr 10 '13 at 12:13

Here's a quick version that uses the matrix approach to completing the square and works for any dimension. It has a couple of checks to make sure that the input is sane, but could have more.

CompleteTheSquare::notquad = "The expression is not quadratic in the variables 1";
CompleteTheSquare[expr_] := CompleteTheSquare[expr, Variables[expr]]
CompleteTheSquare[expr_, Vars_Symbol] := CompleteTheSquare[expr, {Vars}]
CompleteTheSquare[expr_, Vars : {__Symbol}] := Module[{array, A, B, C, s, vars, sVars},
vars = Intersection[Vars, Variables[expr]];
Check[array = CoefficientArrays[expr, vars], Return[expr], CoefficientArrays::poly];
If[Length[array] != 3, Message[CompleteTheSquare::notquad, vars]; Return[expr]];
{C, B, A} = array; A = Symmetrize[A];
s = Simplify[1/2 Inverse[A].B, Trig -> False];
sVars = Hold /@ (vars + s); A = Map[Hold, A, {2}];
Expand[A.sVars.sVars] + Simplify[C - s.A.s, Trig -> False] // ReleaseHold
]


For example:

In[]:= CompleteTheSquare[a x^2 + b x + c y^2 + d y, {x, y}]

Out[]= -((a b^2 c^2 + a^2 c d^2)/(4 a^2 c^2)) + a (b/(2 a) + x)^2 + c (d/(2 c) + y)^2

-

Here is my solution. completeSq calls itself recursively until there is no change.

completeSq[a_. x_^2 + b_. x_ + c_: 0] := -(b^2/(4 a)) +
a (b/(2 a) + x)^2 + completeSq[c]
completeSq[d_] := d


It even works with complex real numbers:

In[236]:= completeSq[
4.1 + z^2 + 2 x + I x^2 + 10 y + -3 x - 12 y^2 + 5.1 z + z^2]

Out[236]= (2.93208 + 0.25 I) + I (I/2 + x)^2 - 12 (-(5/12) + y)^2 +
2 (1.275 + z)^2
`
-