transcendental zeros function



-----Ryan Krauss  wrote: -----

> Is there a Maxima function (or would it be
> easy to write a simple one), that could look at
> an expression and for a range of an input values know which terms will
> never be 0 and factor them out for the sake of easier root searching?

Delete factors that are nonzero on the real line. If you need the zeros
on the complex plane, don't use this function!

trashpositivefactors(e) := block([inflag : 'true],
   e : factor(e),
   e : if mapatom(e) or not(op(e) = "*") then [e] else args(e),
   e : map(lambda([x], if member(sign(x), ['pos, 'neg, 'pn]) then 1 else
   x), e),
   apply("*",e));

(%i2) trashpositivefactors(-(x+1)*(x+2)*(x^2+1)/42);
(%o2) (x+1)*(x+2)

(%i3) trashpositivefactors(1+x+x^2);
(%o3) x^2+x+1

(%i4) trashpositivefactors(sinh(x) * sin(x));
(%o4) sin(x)*sinh(x)

(%i5) assume(x > 0);
(%o5) [x>0]
(%i6) trashpositivefactors(sinh(x) * sin(x));
(%o6) sin(x)

(%i7) trashpositivefactors(cosh(z) * sin(z));
(%o7) sin(z)

(%i8) trashpositivefactors((1 + abs(a)) * exp(-b) * log(a));
(%o8) log(a)

(1) My function trashpositivefactors is untested--it's likely that it
has bugs. For one, factors with an explicit %i will cause
trouble:

(%i32) trashpositivefactors((1+%i*z)*(1-%i*z));
`sign' called on an imaginary argument:

You might be able to fix this problem by replacing 'sign' with
'mysign':

mysign(x) := (x : errcatch(sign(x)), if x = [] then 'bogus else part(x,1));

Another problem is:

(%i18) trashpositivefactors(sin(z)/(z));
(%o18) sin(z)  <-- spurious zero at zero. Yikes!

Fixing this is harder. Maybe trashpositivefactors should accumulate a
list of factors it removes and return them so that they can be tested
later.

(2) You'll discover that Maxima's sign function needs to be improved.

(3) Maxima doesn't have a function 'sign' that takes an interval as an
argument
-- the only way is to use 'assume.'

(4) If you don't care about multiplicities, you could do something like

trashpositivefactors(e) := block([inflag : 'true],
   e : factor(e),
   e : if mapatom(e) or not(op(e) = "*")  then [e] else args(e),
   e : map(lambda([x], if member(sign(x), ['pos, 'neg, 'pn]) then 1 else
   x), e),
   e : map(lambda([x], if not(mapatom(x)) and op(x) = "^" and
   sign(part(args(x),2)) = 'pos then part(args(x),1) else x),e),
   apply("*",e));

(%i29) trashpositivefactors((1 + 2 * z + z^2));
(%o29) z+1

The function 'factor' doesn't factor inside the %pi th power:

(%i30) trashpositivefactors((1 + 2 * z + z^2)^%pi);
(%o30) z^2+2*z+1

So we have to do it again:

(%i31) trashpositivefactors(%);
(%o31) z+1

(5) My functions might help you get started.  They aren't tested -- so be
careful!
There are lots of other things you could do -- a factor of the form abs(e)
could
be changed to e, for example. That might be nicer for some numerical
methods.
Barton