Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

share|improve this question
1  
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
3  
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

8 Answers 8

up vote 12 down vote accepted

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
share|improve this answer
    
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
1  
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}
*)
share|improve this answer

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}
share|improve this answer

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
share|improve this answer

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.

share|improve this answer

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)
   }
 ];
share|improve this answer
    
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
1  
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 *)
share|improve this answer
    
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
1  
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
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.