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
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 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
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
There's a ResourceFunction
for this since 9 Aug 2019:
cs = ResourceFunction["CompleteTheSquare"]
cs[5 x^2 + 27 x - 5, x]
(* -(829/20) + 5 (27/10 + x)^2 *)
cs[5 x^2 + 27 x == 5, x]
(* -(829/20) + 5 (27/10 + x)^2 *)
And, oddly, a helper for ResourceFunction
that does nearly the same thing:
ResourceFunctionHelpers`CompleteSquare[5 x^2 + 27 x - 5, x]
(* -(829/20) + 5 (27/10 + x)^2 *)
ResourceFunctionHelpers`CompleteSquare[5 x^2 + 27 x == 5, x]
(* -(829/20) + 5 (27/10 + x)^2 == 0 *)
Also, AlphaScannerFunctions`CompleteSquare
does the same thing.
CompleteSquare
showed up when I searched for it (something like ? *`*CompleteSquare*
).
$\endgroup$
Commented
Aug 23, 2022 at 18:09
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
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) /.
Solve[Thread[
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}
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)
}
];
CoefficientList[]
, which gives all the coefficients in one blow.
$\endgroup$
Commented
Apr 10, 2013 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 *)
_.
that can be missing from the expression, via @RunnyKine.
$\endgroup$
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]
$\endgroup$
Commented
Apr 10, 2013 at 11:12
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?
$\endgroup$
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
$\endgroup$
Commented
Apr 10, 2013 at 12:13
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
I know this question is pretty old but I want to add a possible solution that I think is simple and worth sharing:
CompleteTheSquare[poly_,x_] := Module[
{cba = CoefficientList[poly, x]},
c = cba[[1]];
b = cba[[2]];
a = cba[[3]];
a(x+b/(2a))^2+(c-b^2/(4a))
]
It is a simple implementation of the algorithm for completing the square.
a
, b
, and c
in Module
, too. (One can also assign them values with {c, b, a} = cba;
, which looks cute.)
$\endgroup$
Commented
Aug 7, 2021 at 23:06