:

## undoing one form of symbolic root

Maple

In this previous post, an example is shown that demonstrates the potential problems that can arise following symbolic conversions such as from sqrt(x^2)  to x^(1/2).

Here x is an unknown symbol. The difficulties include the fact that, while `sqrt` can be smart about simplifying numeric values (eg. integers, rationals) the `^` operator has no such opportunity. Once the conversion from `sqrt` or `root` to `^` has been made there is no usual subsequent opportunity for complete simplification of powers, even when evaluation is done at a numeric value.

In short, eval( x^(1/2), x=4 ) will result in 4^(1/2) and not have the opportunity to simplify to the result of 2, which would be more convenient.

In the previous post, an expression 'q' was shown for which evaluation at a numeric point produced a fractional result whose numerator was zero but whose denominator was a "veiled zero". As was shown, Maple's current behaviour is that zero divided by veiled-zero immediately brings about a result of zero, with no opportunity to detect the exception. The result of zero, for that example, is incorrect.

If, on the other hand,  some smarter resolution of certain `^` terms could instead be done, then a veiled-zero in the denominator might be resolved as being a detectable zero. The final result would be the (much more satisfactory) detection of a division by zero -- a numeric exception event.

Below, I show an experiment toward working around that behaviour. It works by examining the input for one-over-integer powers, when evaluation is to be done at a numeric value. Just prior to actual evaluation, such `^` instances are replaced by effective calls to `root` or `sqrt`.

Note the I have to temporarily redefine `eval` in order to do this. That is seriously changing Maple, because `eval` is used in many hidden and important places. Basically, if `eval` is changed badly then key bits of Maple won't work. Of course, my changes only affect the single Maple session, and are not permanent.

`> # The original problematic example> q := (6*((1/3)*A-1/9))/(36*A-116+12*sqrt(12*A^3-3*A^2-54*A+93))^(1/3);                                   6 (A/3 - 1/9)            q := --------------------------------------------------                                       3      2             1/2 1/3                 (36 A - 116 + 12 (12 A  - 3 A  - 54 A + 93)   ) >   > eval(q, A = 1/3); # :(                                       0 > `eval/F` := proc()>   if nargs=2 and type(1/op(2,args[1]),integer) then>       root(eval(op(1,args[1]),args[2]),1/(op(2,args[1])));>   else>     `^`(eval(op(1,args[1]),args[2]),op(2,args[1]));>   end if;> end proc:>> unprotect(eval): # living on the edge> origeval := eval(eval):>> eval := proc(x)> local b, dx, nx;>   if nargs=0 then>       error "invalid input: eval expects 1 or 2 arguments, but received 0";>   elif nargs=1 then Z(x);>   elif nargs=2 and type(args[2],symbol=numeric) then>       nx := Z(subsindets(numer(x),`^`,t->'F'(op(t))),args[2..-1]);>       dx := Z(subsindets(denom(x),`^`,t->'F'(op(t))),args[2..-1]);>       nx/dx;>   else>       Z(args[1],args[2]);>   end if;> end proc:>> eval:=subs(Z=origeval(origeval),origeval(eval)):> protect(eval);> eval(q, A = 1/3); # :)Error, (in eval) numeric exception: division by zero>> f:=(a-2)/(a-8^(1/3));                                       a - 2                                f := ----------                                          (1/3)                                     a - 8 > eval(f,a=2);Error, (in eval) numeric exception: division by zero>>> ee := (34-sqrt(A^2))^(1/3);                                         2 1/2 (1/3)                           ee := (34 - (A )   ) > eval(ee,A=7); # want result to be 3                                       3 # some sanity checks> eval(ee);                                      2 1/2 (1/3)                              (34 - (A )   ) > eval(ee,A=y*p);                                     2  2 1/2 (1/3)                             (34 - (y  p )   ) > eval('''ee''',1);                                     ''ee'' > eval(ee,[A=7]); # weakness                                       1/2 (1/3)                               (34 - 49   ) > eval(A^(11/2),A=4); # weakness                                         1/2                                   1024 4                                                                                ># Now revert.> unprotect(eval);> eval:=origeval(origeval):> protect(eval);`

Improvements to the (initial, simplistic) methodology would be welcome. This is also expected to be measurably slower than usual `eval`.

acer

﻿