3

I'm getting results that are sensitive to where I place parentheses with respect to operations that are associative1 (and should thus be insensitive to such placement). For example, if I define2

<< Units`; << PhysicalConstants`;
stellarDayTextbook = 1/(1/Day + 1/Convert[SiderealYear, Day])

and then calculate

1/stellarDayTextbook - 1/Day - 1/Convert[SiderealYear, Day]

I get precisely zero, as expected. But if I add parentheses

(1/stellarDayTextbook - 1/Day) - 1/Convert[SiderealYear, Day]

I get

-(3.03577*10^-17/Day)

What's causing this?


1. Remember, this isn't C, it's math: "subtraction" of $x$ is just the addition of $-x$. Check TreeForm.

2. I realize this isn't the definition of a "stellar day", but merely a textbook approximation. The distinction is not material to the question.

orome
  • 12,819
  • 3
  • 52
  • 100
  • Subtraction is associative? http://en.wikipedia.org/wiki/Associative_property – alancalvitti Nov 13 '12 at 16:01
  • @alancalvitti: Ok, ok: go ahead and replace all the - with +-. – orome Nov 13 '12 at 16:05
  • 5
    Just numerical roundoff error here. We know the order of evaluation for the parenthesized version, and clearly the order is different for the unparenthesized version. Use Chop on the result to get rid of the error. – murray Nov 13 '12 at 16:07
  • Sounds to me like @murray pretty much said it; it's just one of the vagaries of inexact arithmetic. – J. M.'s missing motivation Nov 13 '12 at 16:11
  • @alancalvitti It is left-associative, which is what the OP did here. – rm -rf Nov 13 '12 at 16:20
  • @rm-rf: In fact, it's implemented (as my per my comment above) as addition. Try TreeForm[x - y - z]. – orome Nov 13 '12 at 16:23
  • 6
    In any case, floating point operations are not necessarily associative/distributive, even if the underlying mathematical operations are. – rm -rf Nov 13 '12 at 16:26
  • @rm-rf: Yes, good point, as this demonstrates (and that would be a good answer). – orome Nov 13 '12 at 18:29
  • I'm not near an mma installation now, but I'll write an answer a little later. – rm -rf Nov 13 '12 at 18:30
  • 2
    Actually just like in C, addition of floating point (inexact) numbers isn't associative in Mathematica either ... – Szabolcs Nov 13 '12 at 18:53
  • @Szabolcs: Right, the calculation certainly isn't. The parsing of the expression is (unlike some programming languages and calculators). – orome Nov 13 '12 at 18:59
  • FWIW, one aspect of this that surprises me is that the symbolic information provided in the definition of stellarDayTextbook was not consulted. I'd always assumed (I have no idea why) that Mathematica, in addition to performing the numeric calculation, also "checked" what symbolic information it had to see if a purely symbolic manipulation could be used to produce a different result. Here it would have shown that the expression in question was just a rearrangement of the definition of stellarDayTextbook, and produced 0. – orome Nov 13 '12 at 19:00
  • @rm-rf: Thx. I also have a related question. – orome Nov 13 '12 at 19:01
  • @raxacoricofallapatorius Ah, I think I understand now. Do you mean that since if a, b, c don't have values then (a-c) - b and a - c - b evaluate to the same, we should get the same result regardless of parentheses even if we give them values? This raises some interesting questions about the actual evaluation order. – Szabolcs Nov 13 '12 at 19:03
  • @Szabolcs: Essentially, yes, though maybe "could" instead of "should". Since Mathematica has that information (about the structure of the relevant expressions) around, it might have used it either (1) to have calculated both $(a-c)-b$ and $a-c-b$ to see if it got different results or (2) to have used its symbolic knowledge of the fact that (essentially) $a=b+c$ to conclude that either expression must be 0. – orome Nov 13 '12 at 19:14
  • @raxacoricofallapatorius Block[{a = 3.2, b = 2.1, c = 1.1}, TracePrint[(a - c) - b]] suggests that if a and c have values, a - c is evaluated before the associativity rule is applied (I'm not arguing for this behaviour, just noticing it). – Szabolcs Nov 13 '12 at 19:17
  • @rm-rf "I'm not near an mma installation now, but I'll write an answer a little later." It's been a year and then some, perhaps you could make this question answered. I do not fully know what you intended to say. – C. E. Jan 12 '14 at 00:24
  • @Anon Thanks :) I've posted an answer. – rm -rf Jan 12 '14 at 02:13

1 Answers1

10

What you're seeing here is just the impreciseness of floating point arithmetic. It is important to remember that floating point operations are not associative or distributive even if the underlying mathematical operations are. A very simple example demonstrating the lack of associativity:

1. + (1.*^20 - 1.*^20)
(* 1. *)

(1. + 1.*^20) - 1.*^20
(* 0. *)

Much has been said and written about this topic over the years, so instead of repeating, I'll just link you to a good article to read on the subject: D. Goldberg, "What every computer scientist should know about floating-point arithmetic," ACM Comput. Surv. 23, 1 (March 1991), 5-48

rm -rf
  • 88,781
  • 21
  • 293
  • 472
  • As discussed in the comments above, it's interesting that Mathematica does not take advantage of its knowledge of expression structure to produce a more accurate result. – orome Jan 12 '14 at 02:30
  • 1
    @raxacoricofallapatorius its does If one uses exact numbers. (1 + 1*^20) - 1*^20 gives 1 – Nasser Jan 12 '14 at 02:34
  • @Nasser: But only because those calculations are exact, not because Mathematica is removing the parentheses symbolically. – orome Jan 12 '14 at 02:53
  • 1
    @raxacoricofallapatorius Mathematica is not magic. It neither knows what you intended to achieve nor can it feasibly infer that from some kind of analysis of the sum total of all system, package, and user code that it processes. Anyway, this got my upvote for an excellent reference. – Oleksandr R. Jan 12 '14 at 02:59
  • @OleksandrR.: Removing parentheses is "not magic" either, especially for a system that claims to be superior to those that provide "only numerical results, often forfeiting insight" because it gives "exact, general results whenever possible". – orome Jan 12 '14 at 03:11
  • @raxacoricofallapatorius removing the parentheses would not be magic, I agree. To be magical it would have to be correct. – Oleksandr R. Jan 12 '14 at 03:19
  • @OleksandrR.: $(a−c)−b \neq a−c−b$? – orome Jan 12 '14 at 03:37
  • 1
    @raxacoricofallapatorius not necessarily, when you are working with floating point values. Mathematica is essentially stuck between those who want floating point numbers to behave as an exact analogy to the reals, and those who insist that they are legitimate mathematical objects in their own right, with their own special rules of algebra. I think the compromises that have been made to accommodate both of these classes of users are mostly reasonable, but there are obviously limits to what can be done. The important point is to be aware of what you are really doing so as not to be surprised. – Oleksandr R. Jan 12 '14 at 04:01
  • @OleksandrR.: None of the comments are about FP values (the answer addresses that). No one is asking for magic, just something approximating the claims Mathematica makes for itself. – orome Jan 12 '14 at 04:08
  • @raxacoricofallapatorius your example makes it about as difficult as it possibly could be for Mathematica to predict which answer you would have liked. There are ways of getting the "correct" answer, but you choose not to use them and instead insist that the system somehow divines your intent anyway. I hate to burst your bubble, but Mathematica has never claimed to be omniscient. Also, the issue is quintessentially related to floating point arithmetic. If you don't want to talk about that when discussing it, then I don't know what to say to you. – Oleksandr R. Jan 12 '14 at 04:14
  • @OleksandrR.: Ah! We're talking about Nasser's and rm -rf's examples, not mine. – orome Jan 12 '14 at 04:38
  • Interestingly, Wolfram Alpha gives -1 for the second calculation "based on lexical and semantic similarity in Wolfram|Alpha's computable knowledge space". – orome Jan 12 '14 at 13:07
  • @raxacoricofallapatorius You should give it input that it can understand... 1*^20 is Mathematica shorthand for 10^20 and Wolfram Alpha won't understand that. Try this. – rm -rf Jan 12 '14 at 16:38