4
$\begingroup$

I'm trying to write a rule that acts on any number, lists, expression and so on to turn any negative numbers positive.

The simple r = n_ -> Abs[n] works perfectly well for numbers, lists and nested lists, but does not work expressions, such as Exp[-5], which is unaffected by my rule. I can't use the replace function, because I also require my rule to work for other Mathematica inputs, like numbers, lists and nested lists.

Can someone suggest why this does not work? Is it due to the rule not penetrating the expression? An edit to my rule would also be much appreciated.

$\endgroup$

closed as unclear what you're asking by Daniel Lichtblau, user9660, MarcoB, m_goldberg, march Jan 30 '16 at 18:11

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    $\begingroup$ I think it is working, but it's working on Exp[-5]. Trace shows you the sequence of evaluation steps: Trace[Exp[-5] /. r]. Perhaps Exp[-5] /. n_?NumberQ :> Abs[n] is what you're after? $\endgroup$ – Michael E2 Jan 29 '16 at 13:27
  • $\begingroup$ @MichaelE2, using your method, why can we get (-E)^(-5) to return E^5, but we can't get (-2)^(-5) to return 2^5? Changing the -2 to -2.0 doesn't change it either. $\endgroup$ – Jason B. Jan 29 '16 at 13:44
  • $\begingroup$ @JasonB Perhaps Trace and the observation that NumberQ[E] is False leads to an explanation. E.g., (-2)^(-5) evaluates to -1/32 before any rules are applied. See if you can figure out HoldForm[(-2)^(-5)] /. n_?NumberQ :> Abs[n] // Trace -- it stumped me at first. Inactivate[(-2)^(-5)] /. n_?NumberQ :> Abs[n] is the only way I figured out to do what you want. $\endgroup$ – Michael E2 Jan 29 '16 at 14:02
  • $\begingroup$ For Log[1/E], do you want to get 1 or -1? (I.e. do you want Abs[ Log[ Abs[ Abs[1]/Abs[E]]]] or only Log[ Abs[1/E]], respectively?) $\endgroup$ – Eric Towers Jan 29 '16 at 17:44
  • 2
    $\begingroup$ This question needs a good size set of example inputs with desired outputs. Too many people are needing too many guesses to sort out what actually is wanted, and that amounts to wasted time. $\endgroup$ – Daniel Lichtblau Jan 29 '16 at 18:34
5
$\begingroup$

A few more examples provided at suggestion of OP.

Replace[Unevaluated[{Exp[-5], -7, (-2)^(-5), BesselJ[-2, -3], 
    Cos[-5], {-Pi, -E}, Exp[-5 Exp[-5]]}], n_ -> Abs[n], {0, Infinity}]

(* {E^5, 7, 32, BesselJ[2, 3], Cos[5], {π, E}, E^(5 E^5)} *)

may be what you want. (Note:. Unevaluated needed to handle (-2)^(-5).)

Addendum

This can be written as a function by

f = Function[x, Replace[Unevaluated[x], n_ -> Abs[n], {0, Infinity}], HoldAll]

Then,

f@{Exp[-5], -7, (-2)^(-5), BesselJ[-2, -3], Cos[-5], {-Pi, -E}, Exp[-5 Exp[-5]]}
(* {E^5, 7, 32, BesselJ[2, 3], Cos[5], {π, E}, E^(5 E^5)} *)

as before.

$\endgroup$
  • $\begingroup$ Thank you for your help, but I should have made my question clearer (I have just edited it). I require this rule to work for all kinds of mathematica inputs, such as numbers, lists of numbers, Cos[-5] and so on. Therefore, Replace won't work since it is far too specific. $\endgroup$ – Pablo Jan 29 '16 at 13:34
  • $\begingroup$ @Pablo Works for those too. See addition to list of examples. The third argument, Infinity, causes Replace to reach inside functions. The suggestion by MichaelE2 works well too, of course. $\endgroup$ – bbgodfrey Jan 29 '16 at 13:39
  • $\begingroup$ @bbgodfrey I believe Reduce[ expr, n_?NumberQ -> Abs[n], Infinity] might work and be more precise? (Oh, I see that is what MichaelE2 has suggested above) $\endgroup$ – gwr Jan 29 '16 at 13:40
  • $\begingroup$ @gwr Certainly, your suggestion works too, but I am not sure what you mean by "more precise". $\endgroup$ – bbgodfrey Jan 29 '16 at 13:42
  • $\begingroup$ @bbgodfrey While testing ?NumberQ takes time, we will not need to have nested Abs[ ] in a nested expression, but that is what we will get without the filtering. $\endgroup$ – gwr Jan 29 '16 at 13:50
2
$\begingroup$

Exp[-5] is not unaffected by your rule at all; on the contrary,

Trace[Exp[-5]/.n_->Abs[n]]

shows that Exp[-5] is replaced by Abs[Exp[-5]], which is equal to Exp[-5]. If you only want stuff that "looks like" numbers to get replaced, you can use

Replace[Exp[-5],n_->Abs[n]],-1]

which replaces anything that does not have a sub-part, i.e. it would give

e^5

But what about stuff like (-2)^(-5)? Do you want to replace both (-2) and (-5)?

$\endgroup$
  • $\begingroup$ Yes, I want to change every single thing that "looks like" a number from negative to positive before completing the operation. Thank you for your edit on the Exp[-5] example $\endgroup$ – Pablo Jan 29 '16 at 13:25
2
$\begingroup$

In slight modification of @bbgodfrey's excellent answer, what you might use is this:

SetAttributes[ f, HoldAll ];
f[ expr_ ] := Replace[
      HoldForm @ expr, (* prevent any evaluation before replacement *)
      n_ -> Abs[n], (* ?NumberQ would not work then *)
      Infinity
    ]//ReleaseHold;


f[ (-2)^(-5) ]

32

$\endgroup$
  • 1
    $\begingroup$ So you might use Replace[ HoldForm @ expr, n_?NumberQ -> Abs[n], Infinity]//ReleaseHold. $\endgroup$ – gwr Jan 29 '16 at 14:09
  • $\begingroup$ There are subtle differences for HoldForm and Unevaluated which I have not pondered too far. With Unevaluated there is no need for a ReleaseHold. $\endgroup$ – gwr Jan 29 '16 at 14:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.