The problem: "to turn any negative numbers positive"
Proposed solution: Depth-first, post-order traversal with
positivize[expr_] := MapAll[Replace[#, n_?Negative :> -n] &, expr]
-Exp[-5] // positivize
(* E^5 *)
Depth-first, pre-order traversal:
-Exp[-5] /. n_?Negative :> -n
(* 1/E^5 *)
Repeated depth-first, pre-order almost works:
-Exp[-5] //. n_?Negative :> -n
(* E^5 -- seems to work, but... *)
Zeta[-1/10] //. n_?Negative :> -n
(* -Zeta[-(1/10)] *)
Caveat, re the solution
The solution has a potential trap, which is easily seen if doing the reverse, making positive numbers negative.
negativize[expr_] := MapAll[Replace[#, n_?Positive :> -n] &, expr];
Cos // negativize
(* -Cos *)
Explanation: After the
5 is changed to
Cos[-5] automatically reevaluates to
Cos, according to an internal rule implementing the even-function property of
Cos. This does not seem to affect
positivize since the internal rule changes the argument to a positive number. However, there are so many functions, I cannot be sure that there isn't a built-in identity that would interfere with
positivize. Personally, I think positive arguments tend to be preferred, so maybe it's ok.
/.) do a pre-order traversal, the whole negative expression
-Exp[-5] is matched first and replaced by the positive
ReplaceAll then stops and the
-5 is left unchanged.
ReplaceRepeated will continue and replace the
-5. But in the case of
Zeta[-1/10], which is about
-0.417228, it is first replaced by
-Zeta[-1/10] or more explicitly
Times[-1, Zeta[-1/10]]; on the next application of the rule, the
-1 is replaced by
1 -- oops -- yielding
Zeta[-1/10]; then the next replacement yields
-Zeta[-1/10], at which point
ReplaceRepeated exits the potential infinite loop.
Note that whether a minus sign or the numerical value is to be considered "negative" is not made explicitly clear.
Negative tests the numerical value. There is
Internal`SyntacticNegativeQ for testing whether an expression "looks" negative (has a leading minus sign); it could perhaps be used in conjunction with
NumericQ to test whether a numeric expression is written with a minus sign (see references below for example uses).
How to ReplaceAll independent of depth?
How to perform a depth-first preorder traversal of an expression?
Merge Roots of Polynomial, Two ways to speed up slow Integrates? (Can't do either) (