A common question to our tech support team is about completing the square for a univariate polynomial of even degree, and how to do that in Maple. We’ve put together a solution that we think you’ll find useful. If you have any alternative methods or improvements to our code, let us know!

restart;
# Procedure to complete the square for a univariate
# polynomial of even degree.
CompleteSquare := proc( f :: depends( 'And'( polynom, 'satisfies'( g -> ( type( degree(g,x), even ) ) ) ) ), x :: name )
local a, g, k, n, phi, P, Q, r, S, T, u:
# Degree and parameters of polynomial.
n := degree( f, x ):
P := indets( f, name ) minus { x }:
# General polynomial of square plus constant.
g := add( a[k] * x^k, k=0..n/2 )^2 + r:
# Solve for unknowns in g.
Q := indets( g, name ) minus P:
S := map( expand, { solve( identity( expand( f - g ) = 0, x ), Q ) } ):
if numelems( S ) = 0 then
return NULL:
end if:
# Evaluate g at the solution, and re-write square term
# so that the polynomial within the square is monic.
phi := u -> lcoeff(op(1,u),x)^2 * (expand(op(1,u)/lcoeff(op(1,u),x)))^2:
T := map( evalindets, map( u -> eval(g,u), S ), `^`(anything,identical(2)), phi ):
return `if`( numelems(T) = 1, T[], T ):
end proc:
# Examples.
CompleteSquare( x^2 + 3 * x + 2, x );
CompleteSquare( a * x^2 + b * x + c, x );
CompleteSquare( 4 * x^8 + 8 * x^6 + 4 * x^4 - 246, x );
m, n := 4, 10;
r := rand(-10..10):
for i from 1 to n do
CompleteSquare( r() * ( x^(m/2) + randpoly( x, degree=m-1, coeffs=r ) )^2 + r(), x );
end do;
# Compare quadratic examples with Student:-Precalculus:-CompleteSquare()
# (which is restricted to quadratic expressions).
Student:-Precalculus:-CompleteSquare( x^2 + 3 * x + 2 );
Student:-Precalculus:-CompleteSquare( a * x^2 + b * x + c );

For a higher-order example:

f := 5*x^4 - 70*x^3 + 365*x^2 - 840*x + 721;
g := CompleteSquare( f, x ); # 5 * ( x^2 - 7 * x + 12 )^2 + 1
h := evalindets( f, `*`, factor ); 4 * (x-3)^2 * (x-4)^2 + 1
p1 := plot( f, x=0..5, y=-5..5, color=blue ):
p2 := plots:-pointplot( [ [3,1], [4,1] ], symbol=solidcircle, symbolsize=20, color=red ):
plots:-display( p1, p2 );

tells us that the minimum value of the expression is 1, and it occurs at x=3 and x=4.