RootOf

The function RootOf is a placeholder for representing one, many, or all of the roots of an equation in one variable. In particular, it is the standard representation for Maple algebraic numbers, algebraic functions, and finite fields. Maple 18 includes a number of improvements to make it easier to work with.

RootOfs often appear as the result of a call to solve. This happens when solve cannot find an explicit solution for the solution of a non-algebraic equation in one variable.

> solve( cos(x^2) = 2*cos(x)+x, x );
 
RootOf(`+`(`*`(2, `*`(cos(_Z))), `-`(cos(`*`(`^`(_Z, 2)))), _Z))
 

Alternatively, they may be built directly as an abstract representation of a number that satisfies a certain equation: 

> a := RootOf(x^2=2, x);
 
RootOf(`+`(`*`(`^`(_Z, 2)), `-`(2)))

A standard interaction with RootOf is to ask for an exact or floating-point approximation of one or more values represented by the RootOf function. To convert roots representing algebraic numbers to floating-point values (by default the principal root is chosen), use evalf: 

> evalf(a);

1.414213562

To convert to radicals, use convert: 

> convert(RootOf(x^2-2), radical);

`*`(`^`(2, `/`(1, 2)))
 

If the set of all roots is needed, use the allvalues command: 

> {allvalues(a)};

{`*`(`^`(2, `/`(1, 2))), `+`(`-`(`*`(`^`(2, `/`(1, 2)))))}

> evalf({`*`(`^`(2, `/`(1, 2))), `+`(`-`(`*`(`^`(2, `/`(1, 2)))))});

{-1.414213562, 1.414213562}

 

RootOfs can be specified using various selector types: numeric, interval, index, or label, as described in the following sections. 

 

 

Numeric Selectors

The numeric selector is a numerical approximation to the desired root. In previous versions of Maple, evalf and allvalues used the numeric selector as a starting point for a Newton's method evaluation of the root. In Maple 18, the meaning of the numeric selector for RootOfs has been redefined and is more precise.

If c is the value of the numerical approximation, and if the polynomial is univariate with rational coefficients, the closest among all the roots of the polynomial to c is the one selected. As shown further below, if the approximation is ambiguous, an error will be raised by evalf or convert.

> b := RootOf(x^3-2, x, 1.26);
 
RootOf(`+`(`*`(`^`(_Z, 3)), `-`(2)), 1.26)
 
> evalf(b);
 
1.259921050
 

 

Interval Selectors

The interval selector specifies a root within the interval. For Maple18, errors are now raised if there is not at least one root in the interval or bounding box, or if the bounding box is not well-specified. The numbers should be given in the order of the lower-left corner of the box to the upper-right corner of the box (or the left and right endpoints, in the case of a real interval), otherwise, an error will be raised.

The polynomial `+`(`*`(`^`(x, 2)), `-`(x), `-`(1)) contains two roots, as follows: 

> allvalues(RootOf(x^2-x-1, 1/2));
 
`+`(`/`(1, 2), `*`(`/`(1, 2), `*`(`^`(5, `/`(1, 2))))), `+`(`/`(1, 2), `-`(`*`(`/`(1, 2), `*`(`^`(5, `/`(1, 2))))))
 
> evalf([`+`(`/`(1, 2), `*`(`/`(1, 2), `*`(`^`(5, `/`(1, 2))))), `+`(`/`(1, 2), `-`(`*`(`/`(1, 2), `*`(`^`(5, `/`(1, 2))))))]);
 
[1.618033988, -.6180339880]
 

The interval 1 .. 2 is sufficient to select the positive root: 

> RootOf(x^2-x-1, 1..2);
 
RootOf(`+`(`*`(`^`(_Z, 2)), `-`(_Z), `-`(1)), 1 .. 2)
 
> evalf(RootOf(`+`(`*`(`^`(_Z, 2)), `-`(_Z), `-`(1)), 1 .. 2));
 
1.618033989
 

Errors when the interval is invalid: 

> RootOf(x^2-x-1, 2..1);

Error, (in RootOf) the input range 2 .. 1 is invalid
 
> RootOf(x^2-x-1, 1+2*I..2-I);
 
Error, (in RootOf) the input range 1+2*I .. 2-I is invalid
 

Errors when the interval contains no root: 

> RootOf(x^2-x-1, 2..3);

Error, (in RootOf) there is no root of _Z^2-_Z-1 in 2 .. 3
 
> RootOf(x^2-x-1, 1-2*I..2-I);
 
Error, (in RootOf) there is no root of _Z^2-_Z-1 in 1-2*I .. 2-I
 

Index Selectors

The index selector specifies a root by its position according to a predefined ordering of the roots. Roots closer to the positive real line (approaching in a clockwise direction) have lower indices. Ties are broken by the rule that roots with lower absolute values have lower indices.

The following calculation demonstrates the index definition described above. The index of each root of a polynomial is plotted at the root's location in the complex plane.  

> poly := z*(z^8-1)*(z^8-2^8);
 
`*`(z, `*`(`+`(`*`(`^`(z, 8)), `-`(1)), `*`(`+`(`*`(`^`(z, 8)), `-`(256)))))
 

Show where the root with index = 5 is located: 

> convert(RootOf(poly, index=5), radical);
 
`+`(`*`(`^`(2, `/`(1, 2))), `*`(I, `*`(`^`(2, `/`(1, 2)))))
 

Now plot the locations of all the roots, identifying each by its index: 

> pts := evalf[2]([seq(RootOf(poly, index=i), i=1..17)]):

> plots:-display([seq(plots:-textplot([op([Re, Im](pts[i])), i], font = ["Helvetica", "Bold", 12]), i=1..17)],axes=boxed, view=[-2.5..2.5, -2.5..2.5], labels =[Re(z), Im(z)]);
 
Plot_2d

Label Selectors

The label selector provides a way to specify that one root is the same or different than another, without actually determining a value for each root.

Roots with different labels are meant to be different, as demonstrated by the following: 

> alias( c=RootOf(z^3+1, z, label=A) ):
> alias( d=RootOf(z^3+1, z, label=B) ):
> evala( c-d );

`+`(c, `-`(d))

> evala( c^3-d^3 );

0

Label selectors should not be used if the roots are algebraic and need to be evaluated numerically. For example, if the roots are known to be algebraic, then evalf or convert may evaluate two supposedly different roots to the same value: 

> evalf(c-d);

`+`(0., `*`(0., `*`(I)))

> convert(c-d, radical);

0

In this case, an index, numeric, or interval selector should be used instead. The documentation has been updated to provide a warning about this situation. 

 

Specificity of Selectors

The command evalf raises an error if the numeric or interval selector is not sufficiently specific.

> e := RootOf(x^2-x-1, -5..5);

RootOf(`+`(`*`(`^`(_Z, 2)), `-`(_Z), `-`(1)), -5 .. 5)

Error because there are multiple possible roots in the interval: 

> evalf(e);

Error, (in evalf/RootOf) there are multiple values encoded in RootOf(_Z^2-_Z-1, -5 .. 5)
 
> e := RootOf(x^2-x-1, 1/2);

RootOf(`+`(`*`(`^`(_Z, 2)), `-`(_Z), `-`(1)), `/`(1, 2))

Error because the numeric selector is equally distant from the two roots, so it is not sufficient to distinguish between them: 

> evalf(e);

Error, (in evalf/RootOf) there are ambiguous values encoded in RootOf(_Z^2-_Z-1, 1/2)
 

 

Converting Between Different Selectors

RootOfs can now be converted between different (non-label) selectors:

> f := RootOf(x^3-x-1, index=1);

RootOf(`+`(`*`(`^`(_Z, 3)), `-`(_Z), `-`(1)), index = 1)

> g := convert(f, RootOf, form = interval);

RootOf(`+`(`*`(`^`(_Z, 3)), `-`(_Z), `-`(1)), `/`(10349359, 7812500) .. `/`(662358981, 500000000))

> h := convert(g, RootOf, form = numeric);

RootOf(`+`(`*`(`^`(_Z, 3)), `-`(_Z), `-`(1)), 1.324717957)

> convert(h, RootOf, form = index);

RootOf(`+`(`*`(`^`(_Z, 3)), `-`(_Z), `-`(1)), index = 1)

convert also raises an error when the specification of the root is ambiguous: 

> convert(RootOf(x^2-x-1, 1/2), RootOf, form = index);

Error, (in convert/RootOf) there is ambiguity in RootOf(_Z^2-_Z-1, 1/2)
 
> convert(RootOf(x^2-x-2,-2..2 ), RootOf, form=index);

Error, (in convert/RootOf) multiple roots encoded in RootOf(_Z^2-_Z-2, -2 .. 2)
 

 

Improvements in evala-related Procedures

evala -related procedures are improved as a side effect of the changes to RootOf

Additionally, evala-related functions, such as gcd, are now more careful: 

> r[1] := RootOf(_Z^2-2,0);

RootOf(`+`(`*`(`^`(_Z, 2)), `-`(2)), 0)

> r[2] := RootOf(_Z^2-2,index = 1);

RootOf(`+`(`*`(`^`(_Z, 2)), `-`(2)), index = 1)

The numeric selector, 0, is not sufficient to distinguish whether r[1] is the positive or negative root. Therefore, the following gcd computation is ambiguous: if r[1] represents the positive root, then the GCD is `+`(x, `-`(sqrt(2))), but if r[1] represents the negative root, then the GCD is 1. Hence an error is raised: 

> gcd(x-r[1],x-r[2]);

Error, (in evalf/RootOf) there are ambiguous values encoded in RootOf(_Z^2-2, 0)
 

 

Indices Adjusted as Multiplicities Removed

Index selectors are now adjusted, if necessary, as multiplicities are removed from the defining polynomial:

> RootOf(x^5-x^2, index=4);

RootOf(`+`(`*`(`^`(_Z, 4)), `-`(_Z)), index = 3)