Tutorial for the SwitchableRealOnly Package
By Ted Ersek
ersektr@navair.navy.mil

Review of the (Miscellaneous`RealOnly`) package

One of the Standard Packages included with Mathematica is called (Miscellaneous`RealOnly`). This package ensures that  (x^p) returns a negative number when x is Negative, (p) is Rational and Denominator[p] is odd.  Sometimes one wants to ensure that, for example,  ((-8)^(1/3))  returns (-2), and the Miscellaneous`RealOnly` package ensures this is the case.  Once the Miscellaneous`RealOnly` package is loaded the Plot command below will make the graph of an odd function which in some cases is what a user has in mind.

Needs["Miscellaneous`RealOnly`"]

Plot[(x^(1/3)), {x, -8, 8}];

The (Miscellaneous`RealOnly`) package has another feature.  After loading the package complex numbers with imaginary part greater than (10^(-10)) are replaced with the symbol  (Nonreal) before evaluation is complete. The package also ensures most elementary functions return Nonreal if one or more argument is Nonreal.  Consider the example in next cell where (Sqrt[-9]) evaluates to ( 3i ), but is changed to Nonreal. Then (x + Nonreal) evaluates to NonReal and a message is posted.

{x + (Sqrt[9]), x + (Sqrt[-9])}

Problems with the (Miscellaneous`RealOnly`) package

First of all the Miscellaneous`RealOnly`package provides no easy way to return to the normal behavior once the package is loaded.  This shortcoming was noted in the MathGroup by Dave Park.

A second problem is that once the package is loaded Solve and Roots will, in rare cases, incorrectly indicate that an equation has Nonreal solutions.  If the (Miscellaneous`RealOnly`) package hasn't been loaded during the current Mathematica session, Solve finds all solutions of the equation (x^3+6x^2-9 == 0) when the next cell is evaluated.

Solve[x^3 + 6  x^2 - 9 == 0, x]

At first it may appear the solutions above are complex numbers. However, the next cell shows that all imaginary parts simplify to zero. So the three solutions are actually real.

FullSimplify[Im[x /. %]]

If one attempts to solve the above equation after loading the RealOnly package the complex numbers in the solution are changed to the symbol Nonreal without checking to see if the complex parts cancel. As a result we are incorrectly told that the solutions to the equation are Nonreal. This problem and example demonstrating the problem are mentioned in the source code for the RealOnly package.

Needs["Miscellaneous`RealOnly`"]

Solve[x^3 + 6  x^2 - 9 == 0, x]

In the next cell we see Roots has the same problem as Solve.

Roots[x^3 + 6  x^2 - 9 == 0, x]

The SwitchableRealOnly package

The accompanying package (SwitchableRealOnly.m) should be stored in the (AddOns\ExtraPackages\Miscellaneous) directory. Once the package is stored in the appropriate directory it can be loaded by evaluating the next cell.  However, you must ensure the Miscellaneous`RealOnly` package was not loaded during the current Mathematica session.

Needs["Miscellaneous`SwitchableRealOnly`"]

By default the package has RealOnly processing disabled.  You need to evaluate RealOnly[] to enable RealOnly processing.

RealOnlyOn[];
Plot[(x^(1/3)), {x, -10, 10}];

With the SwitchableRealOnly package Solve and Roots don't have problems.

Below we see the SwitchableRealOnly package doesn't prevent Solve and Roots from retuning correct solutions to the problems considered earlier.  If RealOnlyOn[] was evaluated the solutions are transformed into forms that don't involve complex numbers before complex numbers are changed to the symbol Nonreal.

Solve[x^3 + 6  x^2 - 9 == 0, x]

N[%]

Roots[x^3 + 6  x^2 - 9 == 0, x]

N[%]

In the next example we get one real solution and {x->Nonreal} for two solutions that actually are complex.

Solve[(x - 3) ((x^2) + 2  x  + 6) == 0]

Switch back and forth between normal Mathematica results and RealOnly results.

After loading the SwitchableRealOnly package we are told the cube root of (-8.0)  is -2.0.

(((-8.0))^(1/3))

We may need to switch from RealOnly processing to normal Mathematica behavior, and this can be done by evaluating  RealOnlyOff[].

RealOnlyOff[]
(((-8.0))^(1/3))

For the equations we considered earlier, we now obtain the standard Mathematica solutions.

Solve[x^3 + 6  x^2 - 9 == 0, x]

Solve[(x - 3) ((x^2) + 2  x  + 6) == 0]

Next we turn RealOnly processing back on.

RealOnlyOn[]
(((-8.0))^(1/3))

Solve[x^3 + 6  x^2 - 9 == 0, x]

A warning is posted if Solve of Roots give Nonreal as a solution when they shouldn't

After loading the package Solve and Roots uses ComplexExpand, TrigExpand and Together to try and make imaginary parts cancel, but only when this is likely to happen. If imaginary parts didn't cancel Simplify is used to try and cancel the imaginary parts. If after all that the imaginary parts still didn't cancel the complex parts are replaced with the symbol Nonreal, and an appropriate message is posted.

This situation is simulated below by causing TrigExpand and Simplify to do nothing with an expression

Unprotect[TrigExpand, Simplify];
TrigExpand[expr_, ___] := expr;
Simplify[expr_, ___] := expr

Solve[x^3 + 6  x^2 - 9 == 0, x]

Before continuing the normal behavior of TrigExpand and Simplify should be returned by evaluating the next cell.

DownValues[
          TrigExpand] = DownValues[
            Simplify] = {};
Protect[TrigExpand, Simplify];

Does the SwitchableRealOnly cause problems with Reduce, SolveAlways, Eliminate or other functions?

I would not be surprised to learn that both the RealOnly and SwitchableRealOnly packages cause problems with SolveAlways, Reduce, Eliminate, Eigenvectors or other built-in functions that need to solve polynomial equations in at least some cases.

If you find problems created by loading the improved RealOnly package you can pass the word to the author at 
ersektr@navair.navy.mil