I want Mathematica to express the equation $$-11 - 2 x + x^2 - 4 y + y^2 - 6 z + z^2=0$$ in the form $$(x - 1)^2 + (y - 2)^2 + (z - 3)^2 - 25=0$$ How do I tell Mathematica to do that?
8 Answers
You can use custom transformation rules, for example:
-11 - 2 x + x^2 - 4 y + y^2 - 6 z + z^2 //.
(a : _ : 1)*s_Symbol^2 + (b : _ : 1)*s_ + rest__ :>
a (s + b/(2 a))^2 - b^2/(4 a) + rest
returns
(* -25 + (-1 + x)^2 + (-2 + y)^2 + (-3 + z)^2 *)
The above rule does not account for cases where b
is zero, but those are easy to add too, if needed.
-
1$\begingroup$ @minthao_2011 Mathematica auto-sorts things (
Plus
isOrderless
), so you will have a hard time achieving this. $\endgroup$ Commented Feb 23, 2013 at 16:19 -
9$\begingroup$ @minthao_2011 You need
% // PolynomialForm[ #, TraditionalOrder -> True]&
$\endgroup$– ArtesCommented Feb 23, 2013 at 16:35 -
2$\begingroup$ Leonid, is there any reason you are using
x:_:1
rather thanx_:1
etc.? $\endgroup$ Commented Feb 24, 2013 at 7:24 -
1$\begingroup$ @Mr.Wizard Re:
x_:1
- yes, equivalent. Re: the logic - sorry, no time right now, will do later. This is a basic process of completing the square, nothing more. $\endgroup$ Commented Feb 24, 2013 at 15:07 -
1
A different route:
(* polynomial depression *)
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}]]]
tst = -11 - 2 x + x^2 - 4 y + y^2 - 6 z + z^2;
vars = {x, y, z};
{cnst, lin, quad} = MapAt[Diagonal, Normal[CoefficientArrays[tst]], {3}];
cnst + Total[MapThread[depress[#1 FromDigits[{##2}, #1]] &, {vars, quad, lin}]]
-25 + (-1 + x)^2 + (-2 + y)^2 + (-3 + z)^2
-
$\begingroup$ This method does not work with mixed products variables in the polynomial. E.g. Thies Heidecke's second example: x^2 - 4 x y + y^2 + 6 x - 4 (see below). $\endgroup$ Commented May 4, 2019 at 6:24
-
$\begingroup$ It wasn't designed for, and shouldn't work on, polynomials containing a cross-term like
x y
. Conventionally (e.g. applications involving conic sections or quadric surfaces), one would apply something like rotation of axes to remove the cross term before one can do completing the square. $\endgroup$ Commented Jul 28, 2019 at 2:34
eq = (x - a)^2 + (y - b)^2 + (z - c)^2 - d;
sol = SolveAlways[{-11 - 2 x + x^2 - 4 y + y^2 - 6 z + z^2 == eq}, {x, y, z}]
eq /. sol // PolynomialForm[#, TraditionalOrder -> True] &
(* {{d -> 25, a -> 1, b -> 2, c -> 3}} *)
(* {(x-1)^2+(y-2)^2+(z-3)^2-25} *)
eq = (x - a)^2 + (y - b)^2 + (z - c)^2 - d;
Solve[ForAll[{x, y, z}, -11 - 2 x + x^2 - 4 y + y^2 - 6 z + z^2 == eq], {a, b, c, d}]
(*{{a -> 1, b -> 2, c -> 3, d -> 25}}*)
-
1$\begingroup$ Your answer depend on the number 25. $\endgroup$ Commented Feb 25, 2013 at 10:50
-
1
An algebraic one:
h = -2 x + x^2 - 4 y + y^2 - 6 z + z^2 == 11;
((# /. {x -> 0, y -> 0, z -> 0}) + h[[2]] == #) &@
Total[(#2/2/Sqrt@#3 + Sqrt@#3 #4)^2 & @@@ (Join[CoefficientList[h[[1]], #], {#}] & /@ {x, y, z})]
(*
25 ==(-1 + x)^2 + (-2 + y)^2 + (-3 + z)^2
*)
-
$\begingroup$ I don't understand your answer. The right hand side must be 25. Your answer is 11. $\endgroup$ Commented Feb 25, 2013 at 5:43
-
$\begingroup$ @minthao_2011 Sorry, I forgot one term, corrected now $\endgroup$ Commented Feb 25, 2013 at 6:05
The following routine tries to eliminate the linear terms by completing the square for arbitrary number of variables:
CenterPoly[poly_] := Module[{a, b, c, u, vars},
vars = Variables[poly];
{c, b, a} = {#[[1]], #[[2]]/2, (#[[3]] + Transpose[#[[3]]])/2} &@
Normal@CoefficientArrays[poly, vars];
u = PseudoInverse[a].b;
(#\[Transpose].a.#)[[1, 1]] &[{vars + u}\[Transpose]] + c - u.a.u
]
In case that the polynomial is not expressable solely in quadratic terms it uses the PseudoInverse
to get a representation that gets as close to purely quadratic as possible.
CenterPoly[-11 - 2 x + x^2 - 4 y + y^2 - 6 z + z^2]
(* (x - 1)^2 + (y - 2)^2 + (z - 3)^2 - 25 *)
CenterPoly[x^2 - 4 x y + y^2 + 6 x - 4]
(* (x - 1)*(x - 2(y - 2) - 1) + (y - 2)*(-2(x - 1) + (y - 2)) - 1 *)
-
$\begingroup$ In my opinion, your code becomes clearer when you replace your last line by
(vars+u) . a . (vars+u) + (c-u . a . u)
. Or even by{vars, u, a, (c-u . a . u)}
if you want to bring out the details of the completion of the square more explicitly. $\endgroup$ Commented Mar 7 at 8:19
The operation of completing the square with respect to a specified variable is realized by the function CompleteTheSquare
in the Manipulations set of routines from David Park's add-on presentations. In your example:
expr = -11 - 2 x + x^2 - 4 y + y^2 - 6 z + z^2;
<< Presentations`
CompleteTheSquare[CompleteTheSquare[CompleteTheSquare[expr, x], y], z]
(* -25 + (-1 + x)^2 + (-2 + y)^2 + (-3 + z)^2 *)
-
4$\begingroup$ You could express the last line neatly with a fold:
Fold[CompleteTheSquare, expr, {x, y, z}]
$\endgroup$ Commented May 22, 2013 at 8:36 -
$\begingroup$ @ThiesHeidecke: Sure,
Fold
simplifies the code. I was merely trying to point out that a user need not write --perhaps ought not to have to write -- his own code for such a common operation as completing the square. $\endgroup$– murrayCommented May 22, 2013 at 13:35 -
$\begingroup$ Where should I get the
Presentations`
package? $\endgroup$– user69323Commented Feb 10, 2020 at 5:48 -
$\begingroup$ @murray Dear Murray, on my machine Presentations, stopped working. It either happened with passing to Win.10, or to a previous Mma version two versions ago. I cannot tell exactly. I tried to contact David Park and failed. Evidently, Presentations works for you. Could you please kindly comment on this. $\endgroup$ Commented Oct 3, 2021 at 17:32
-
$\begingroup$ @AlexeiBoulbitch: What exactly do you mean by "stopped working"? It's working for me with Mathematica 12.3 under macOS Big Sur 11.6. As I recall, there a few names in the package, e.g. EulerAngle that are shadowed by names now in the Mathematica kernel and I had to modify Presentations so as to change the names to something like DPxxx instead of xxx. $\endgroup$– murrayCommented Oct 4, 2021 at 21:27
What about this:
This is your left-hand-side:
expr1 = - 11 - 2 x + x^2 - 4 y + y^2 - 6 z + z^2;
expr2=expr1 /. {x -> X + 1, y -> Y + 2, z -> Z + 3} // Simplify
The result is:
-25 + X^2 + Y^2 + Z^2
Now back to old notations:
expr2 /. {X -> x - 1, Y -> y - 2, Z -> z - 3}
The result is:
-25 + (-1 + x)^2 + (-2 + y)^2 + (-3 + z)^2
My way for this is:
eq = (x - a)^2 + (y - b)^2 + (z - c)^2 + d;
eq == 0 /. Solve[ForAll[{x, y, z}, -11 - 2 x + x^2 - 4 y + y^2 - 6 z + z^2 == eq]] // TraditionalForm
(* {(x-1)^2+(y-2)^2+(z-3)^2-25} *)
-
$\begingroup$ This solution is already shown: mathematica.stackexchange.com/a/20159/1871 $\endgroup$– xzczd ♦Commented Apr 21, 2023 at 3:56