10

I am using Mathematica 11.1, and I stumbled upon this strange response using the Abs function.

FullSimplify[Abs[x],x<0]
(* Abs[x] *)

while, for example

FullSimplify[Abs[x],x>0]
(* x *)

as expected.

My question: Why doesn't Mathematica simplify Abs[x] to -x when it is given the extra information x<0? Could it be on purpose?

I looked for duplicates, but I could not find a question that was spot on. I'm sorry if I missed some question.

mickep
  • 497
  • 2
  • 15
  • according to help, Abs[z] is left unevaluated if z is not a numeric quantity So really, both cases should be left unevaluated. But looking at Reduce[Abs[x] == x] it says Re[x] >= 0 && Im[x] == 0 so it seems like this is special case where Abs[z] is simplified to z. But help says it should be unevaluated if z is not numeric! – Nasser Apr 23 '17 at 17:35
  • @Nasser Thank you for the comment. Does those "unevaluated" rules apply also when FullSimplify is applied? Maybe not. Always. It is still a bit confusing to me, if I per default have to count minus signs... – mickep Apr 23 '17 at 17:47
  • 2
    This example is discussed in the Documentation for ComplexityFunction (see > Scope there). – Ray Shadow Apr 23 '17 at 17:51
  • Thank you for that link @Shadowray. This confirms it is really by design. – mickep Apr 23 '17 at 17:54
  • fyi, Maple does this operation directly: Mathematica graphics – Nasser Apr 23 '17 at 19:10

2 Answers2

13

Mathematica considers Times[-1,x] to be a more complex expression than Abs[x].

If you change the complexity function you can get the result you expect, e.g.

FullSimplify[Abs[x], x < 0, ComplexityFunction -> (Count[#, Abs, -1] &)]
(* -x *)
Simon Woods
  • 84,945
  • 8
  • 175
  • 324
  • Thank you, that is interesting. I'm a bit surprised that it then considers (for example) the output $$\frac{1}{2-x}+\frac{1}{1+|x|}$$ to be simpler than $$\frac{3-2x}{2-3x+x^2}$$ when running FullSimplify[1/(1 + Abs[x]) + 1/(1 + Abs[x - 1]), x < 0]. If one changes to 0<x<1 or x>1 as option instead, one gets rid of Abs. Appearantly, what is simpler for me is not simpler for Mathematica. Again, thank you! I will accept this answer unless someone will find a much more convincing answer in the next few days. In the meantime you have an upvote! Cheers! – mickep Apr 23 '17 at 17:45
  • @mickep Read ComplexityFunction under Properties & Relations. The system needs an objective measurement of complexity. This link will give you the definition of complexity it uses by default, and will tell you how to define your own. – Szabolcs Apr 23 '17 at 18:34
  • I guess the real question is why the expression is Times[-1,x] rather than just Negate[x] or something. It's not like the OP wrote -1*x... – user541686 Apr 23 '17 at 19:32
  • 1
    @Mehrdad That seems like a reasonable optimisation to do. It doesn't seem useful to have Negate while there is already a more general construct that suffices, and that isn't that much more complicated. – tomsmeding Apr 23 '17 at 20:00
  • 1
    @mickep For related issues see this answer: FullSimplify does not work on this expression with no unknowns. It may appear to be version dependent. – Artes Apr 24 '17 at 06:31
  • @Artes Thank you, that is a bit mind blowing. I somehow accept that it is difficult to define what a FullSimplify command should return. In the case you link to and in the case in this question, I think it gives a non-optimal return. But all comments and the answer here has opened up my eyes that the problem is really to write a "perfect" FullSimplify command, giving results considered easy by humans and computer, yet being powerful. I will now accept the current answer, since that explains why the result is as it is. – mickep Apr 24 '17 at 06:39
  • @mickep: It's not even that it's hard, it's that it's not even a well-defined operation in the first place. Humans could easily disagree about the correct answer. For example, some might prefer $(x - 1)/(x + 1)$ to be simplified to $1 - 2/(x+1)$, and some might not... – user541686 Apr 24 '17 at 07:58
1

In:

Simplify[Abs[x /. x -> -y], x < 0 && y > 0 ]  /. y -> -x

Out:

-x
webcpu
  • 3,182
  • 12
  • 17