Re: Why Mathematica does not issue a warning when the calculations
- To: mathgroup at smc.vnet.net
- Subject: [mg117698] Re: Why Mathematica does not issue a warning when the calculations
- From: Richard Fateman <fateman at eecs.berkeley.edu>
- Date: Wed, 30 Mar 2011 04:09:17 -0500 (EST)
On 3/28/2011 11:47 PM, Daniel Lichtblau wrote: > ----- Original Message ----- >> From: "Richard Fateman"<fateman at eecs.berkeley.edu> >> To: "Daniel Lichtblau"<danl at wolfram.com> >> Cc: "Richard Fateman"<fateman at cs.berkeley.edu>, mathgroup at smc.vnet.net >> Sent: Monday, March 28, 2011 11:32:41 PM >> Subject: Re: [mg117570] Re: Why Mathematica does not issue a warning when the calculations >> On 3/28/2011 4:36 PM, Daniel Lichtblau wrote: >>> Richard Fateman wrote: >>> >>> (DL) >>>> [...] If this is not deemed to qualify as >>>>> the type of situation you describe [...] >>>>> , then the more direct variant below will certainly suffice. >>>>> >>>>> In[36]:= b1 = With[{prec=10}, >>>>> Block[{$MinPrecision=prec,$MaxPrecision=prec}, >>>>> SetPrecision[-251942729309018542,prec] + (6 + Sqrt[2])^20]] >>>>> Out[36]= 0.6619679453 >>>>> >>>>> In[37]:= b2 = With[{prec}, >>>>> Block[{$MinPrecision=prec,$MaxPrecision=prec}, >>>>> SetPrecision[-251942729309018542,prec] + (6 + Sqrt[2])^20]] >>>>> Out[37]= 0.68777820337396297032 >>>>> >>>>> In[38]:= b1 == b2 >>>>> Out[38]= False >>>>> >>>>> This is truncation at work, behind the scenes. >>> (RJF) >>>> Again, these are two different functions, and there is no reason >>>> for >>>> them to result in the same answer. >>> Heh. This is quite not the case (and I don't mean "not quite"...) >>> >>> The function being applied is >>> >>> f(x) = x + (6 + Sqrt[2])^20 >> It is clearly not the function being applied in either case, as a >> simple >> perusal of the text shows. > Not sure what you think it is. Anyone reasonably familiar with Mathematica > bigfloat numerics will recognize it as a fixed precision evaluation of > exactly that function. Yes, a fixed precision evaluation to a different precision. To me there are two textually different functions. It is as though you were saying With[{flag=RED}, f[x,flag]] and With[{flag=GREEN}, f[x,flag]] Perhaps what you might wish to say is With[{prec=Precision[x]}, ...] But then it is clear that you are testing a quality of x that varies with the precision of x, so that even if x1==x2, their precisions may differ, and so the results may differ. I think the issue you are trying to raise is that any system with variable precision must decide on some precision to use to evaluate constants like sqrt(2). If that precision is derived from the precision of a nearby float (not its value), then that constant, or the expression involving it, may come out differently for different precisions. That's not a requirement, though. Here is a simpler example: recall that sqrt(2) = 1.414... Note that in Mathematica, a= 1.4`2 and b= 1.41421'5 are == to each other and to Sqrt[2]. So what do you do for computing precision with Sqrt[2]-a? and for Sqrt[2]? You could, in effect, compute Sqrt[2] to the precisions of a and b respectively, in which case the answers would be approximately 0.0 and 0.0. You could take the VALUES of a and b and the VALUE of sqrt(2) [but how precise?] and compute 1.4142135623... - 1.4 and get 0.014213... and 1.4142135623.. -1.41421 and get 0.0000035623... . This version leaves open the question of how precise,(and would not be the Mathematica way -- since it asserts in passing that 1.4`2 is known to be 1.4000000000000... ) How do other systems choose the precision for evaluating sqrt(2)? See later. > If you translate it to other programs it > will be even more obviously just that(no With...Block... to > sow confusion). Aha, I finally see your point here. You think that by using With [{prec=10 }....] you are doing what non-Mathematica programs do, silently. That is, you believe they scan all the numbers in the expression and find the precision with which to evaluate the Sqrt[2]. Whether to use the lowest or highest precision, who knows. In this case there is only one precision and so it doesn't matter. What is essential here, and which I now see I missed, ( because it is inconsistent with how some other systems actually work), is your assumption that the precision of the input would be determined in this way. > I cannot tell if you are simply not understanding the code, or > intentionally making up junk. I will admit to misunderstanding the intention of the code. I try not to make up junk. > I'm not even sure which would be > the more charitable assumption, given your professional background. > One can perhaps understand my frustration, given that you have me > trying to nail jello to a wall. > > > (DL) >>> The inputs are both equal to -251942729309018542 >>> >>> In[2]:= SetPrecision[-251942729309018542,10] == >>> SetPrecision[-251942729309018542,20] >>> Out[2]= True >> Actually, they are "==" when you test in Mathematica, but they are not >> the same, as you can see by running them through InputForm. > No argument. But your claims were in regard to "equal" values, in the sense > of mathematics. Not "same" values in the sense of inner representation. > > >> Call them a and b, resp. to precision 10 and 20. >> So for a start, they are distinguishable. Indeed, let p= a-b. p== >> 0``-7.401301829825771, whatever. Now you may say that p is equal to >> zero, because Mathematica also says p==0. but if it is, it is >> certainly >> a strange zero. The USUAL zero has the property that 5+p==5. In this >> case, 5+p==p. Indeed, looking at the input forms it appears that >> InputForm[p] is character by character the same as InputForm[p+5]. >> Oh, you might also be distressed to note that a==b, but also >> a==b+10^8. a===b+10^7, but not 10^8. whoa. >> >> But I digress. I shouldn't argue against this part of your argument, >> since clearly in Mathematica, a==b. > Right. Another reason would be that I already went on record as agreeing > the above has its peculiarities. Mind you, I do not think they are > especially "bad". Just peculiar. > > > (DL) >>> This is exactly the situation you had requested. > (RJF) >> OK, I agree. Mathematica's notion of == is such that these two items >> test equal. Indeed, since Mathematica appears to keep all the digits >> of this particular exact integer around, and just slosh the >> "precision"... they have the same digits, just that more or less of >> them are hidden. > While that is quite true, it is not pertinent to the fixed precision > evaluation I produced. In particular, you will see similar behavior > from trying the same evaluation in other programs. > > >> For example, Round[a] -- miraculously this 10 digit number rounds >> exactly to an 18 digit integer! Studying the properties of >> floating-point arithmetic using Mathematica would be quite a >> challenge. > No argument. It might be a chore, and indeed I doubt Mathematica > would be good for that purpose without serious care taken on the > part of the person writing the lectures (or whatever). > > (RJF) >> On the other hand, not all digits of all numbers are kept around: >> Round[SetPrecision[100!,20]]-Round[SetPrecision[100!,10]] is not zero! >> But for 25!, it is. >> >>> I mention this in careful detail in case anyone is (a) still reading >>> this and (b) failing to see exactly how the example fits the bill. >> OK on (a) and (b). >>> To be more specific, here is what you had earlier stated. >>> >>> "the fact that 2.0000==2.000000000 is True (etc) means that >>> a==b and both a and b are numbers, does not mean that f[a]==f[b] [in >>> Mathematica]. I view this as problematical, even if most people >>> don't >>> ever even notice it." >> OK, you provided an example that shows a == b, f[a]=!=f[b], in >> Mathematica. > I provided considerably more. > > I showed that this happens with fixed precision. So you will > see it with other programs as well, provided they support an > equality test that allows for > lower precision bignum == higher precision bignum > I moreover showed that at least one such program has that > behavior. > You showed this for the case where the evaluation of an expression is done differently for different precisions because the evaluation mechanism extracts from the inputs, an extra parameter, namely "precision" and does a different calculation. If you had said so in the first place it would have been clearer (to me). If the system's evaluation program determines the desired precision by some other mechanism, something that is actually pretty likely, then your simulation in Mathematica is simulation of something that isn't pertinent. For example is there a global "precision" (this is common) that governs the calculations? Or is the precision is determined by the target location as for an assignment z=f[x], look at the precision of the "container" for z. This is the method used by MPFR, which I think Mathematica uses internally. >> (though the two functions are different...) But your effort agrees >> with >> my point, that a==b does not mean f[a]==f[b] in Mathematica. > Or several other programs, I dare say. Did you try any of them > on the example I showed? > Um, try them using some other computer algebra system? For those numbers, a is not equal to b, so the example doesn't work. >> So now we try to find another program that does the same thing; >> showing >> that Mathematica is not alone here. >> In fact you contend that ALL programming systems must do the same >> thing. > Not so. I contend that any program that claims 2.000==2.0000000 > will do what I showed. You, as well as I ,fall into thinking inside a box. You assume that the precision of the computation of an expression is derived from the (lowest?) precision of any of the constituent parts. I assume it is not. > Programs that do not support the above > equality are immune from this. > But they probably also don't > get much usage. Frankly, any program with arbitrary precision > bigfloats that claims 2.0000!=2.0000000 is probably on some > scrap heap. > > (DL) >>> You added shortly afterward: >>> >>> "If you have a true function f, that is a procedure whose results >>> depend only on its argument(s), then when A is equal to B, f(A) >>> should be equal to f(B). This is fundamental to programming and to >>> mathematics, but is violated by Mathematica." >>> >>> What I showed was an example in which it would be violated by any >>> program, working in fixed precision arithmetic, that also claims >>> 2.0000==2.000000000. I suspect this applies to at least a few of the >>> programs that implement bigfloats. You might recognize one such >>> below. >>> >>> type(2.0000=2.000000000, 'equation' ); >>> true > (RJF) >> OK, now this is a subtle point: >> >> it doesn't matter what program this is, because here is a program that >> says that two numbers of different (apparent) precision, or which are >> at least typed in differently, can be equal as values. I don't have a >> problem with that at all, and I don't see any issue since extending >> 2.0000 to more digits by adding zeros is the same. Or another way of >> doing this is to notice that both 2.0000 and 2.0000000 are exactly the >> same rational number, in fact the integer 2, and as such they are >> numerically equal. >> >> If, however, they are distinguishable, say, by checking the precision >> associated with the value, they are not the SAME. They are not >> identical. > True, and yet irrelevant, because... > > >> Consider the program in Mathematica, f[x_]:= N[Pi,Precision[x]]. >> Clearly f[a] and f[b] will be different. > ...Again I remind you that your original remarks, and request for > an example, were in reference to equality. If the issue is > one of "sameness", it even becomes more difficult to get > Mathematica to show the bad behavior. Maybe slightly more difficult, but still one can create two numbers that differ in the last bit and they are still SameQ.... > Also somewhat less important, > because equality testing is not usually done via SameQ. > > That said, I agree Mathematica is a bit tricky in SameQ semantics with > regard to retaining of hidden guard bits and related matters. > > >> However you offer two different programs, one of which sets precision >> to 10, and the other to 20. >> >>> Summary statement: What you wrote to indicate why my example does >>> not >>> qualify strikes me as elaborate gyration. (repeating... because you view the external With[{prec=...} ] as implied by some [non-Mathematica] program, and I view that as a specific intrusion into the non-Mathematica program required to show the behavior we are looking for. >> OK, here is what I think SHOULD happen. I use a hypothetical computer >> algebra system that resembles Mathematica but not entirely... >> OK, here is what I think SHOULD happen. I use a hypothetical computer >> algebra system that resembles Mathematica but not entirely... >> >> exact= -251942729309018542; >> a=SetPrecision[exact, 10] --> answer is -2.519427293 * 10^17 or >> something very close to that in binary >> b=SetPrecision[exact, 20] --> answer is -2.5194272930901854200*10^17 >> >> a-b --> convert both to longest precision and subtract. > Why does this make sense? You are manufacturing digits (which > happen to be zero) for the lower precision value. Yep. > This will > do Really Bad Things if the underlying representation is > binary-based. Nope. You add binary zeros. > In effect you'd be putting garbage right where > you are trying to avoid it. Nope. Consider representing the integer 10 as a float. Do you mind adding decimal zeros or binary zeros to get 10.0000000000000000 ? Are you adding garbage? I think not. Say that you have the single-float 10.0. Do you think that it represents the same number as the integer 10? Or do you think it represents 10.000000xyzw .. where xyzw could be any digits at all? Now if that 10.0 were, say, a measurement that you knew was approximate, ok. But a computationally more useful model (in the opinion of most people) is that the single-float 10.0 is a compact representation of exactly the real number 10, that happens to have an exact representation in decimal or binary floating-point format. This model allows you to do careful analysis of errors etc. You can even simulate the other model with xyzw fuzz, using this. It is much harder to simulate the exact representation idea if the arithmetic you are presented with has the xyzw fuzz already, and you have to do gyrations to "get the fuzz out". > I'm not sure that adding binary (as opposed to decimal) zeros > would be any better an idea, in this setting. It is the same for integers. For fractions it is also about the same. Unless you are wedded to the necessity of exact representation of certain decimal quantities such as 0.01. This has an advantage for bankers, and especially in inflated currencies or long-running mortgage payment calculations. > Anyway, this is your desired semantics so presumably you think > this behavior is fine. I raise the issues mostly to indicate why > I do not think it is such a good direction to take. Yep. I think that adding zeros (even binary zeros) is much preferable to adding fuzz. > >> Answer is >> -7.30704*10^5 NOT ZERO. By contrast, Mathematica effectively >> converts both to the SHORTEST precision and subtracts. >> >> a==exact is False. The number format for a doesn't represent all the >> digits in exact >> b==exact is True. The number format for b DOES represent all the >> digits. >> a==b is False. This maintains the transitivity of the >> mathematical equality relation. >> >> now define the function f[x,newprec]:= N[x+(6+sqrt(2))^20 ,newprec] >> >> f[b,n] == f[exact,n] FOR ALL n, because b==exact in this system. > This will in general not be achievable, if n is larger than the > precision of b. At least not with semantics that does comparison > by raising rather than lowering precision. In this case b and exact represent the same integer, b in a floating-point format, exact is in an integer format. This should assure that f computes the same value. > >> f[a,n] =!=f[exact,n] except for n<10 or so. This function gives >> different answers for different input. >> f[a,n]=!= f[b,n] ditto. >> >> but now you say, what if I don't want to specify newprec? You have a >> few choices. >> For example, let newprec be the highest precision of any number in the >> expression. >> or newprec could be some global precision set outside f. >> or convert everything to hardware floats (ugh) >> [...] > (DL) >>> Okay... >>> Let me turn around the question. In the present statement of the >>> problem, when is Mathematica claiming >>> a==b, f(a)!=f(b), AND precision is the same for both? > (RJF) >> Because the precision is generally concealed from the user, most >> people >> don't take the extra effort to look for it. >> If a==b and their precision is the same or not, who would know? >> >> But since you ask, here is an example. >> >> r0000`5 >> s0003`5 >> f[x_]:=Round[x] >> >> note that Mathematica says r==s, and they both have the same >> precision, >> 5. (oh, r==s-13, as well) >> >> f[r] != f[s] is true. QED > Nice example. It shows a bit of pathology, which is to say it is in the gray area > between a Mathematica weak spot and programmer "error" (for not checking that > precision is insufficient for the task at hand. But you would be quite right to > point to such behavior as being unintuitive and hence posing trouble for the unwary. Thanks. > > (DL) >>> I think what you want is a different language... > (RJF) >> Or the same language with different semantics. > Which would be sufficiently alien to Mathematica as to make it a > different language. Actually, I doubt it. Indeed, if one were able to drop into Mathematica a different arithmetic model, how much of the test suite would run exactly the same? Of course those parts that explicitly rely on floats would mostly not do the same thing. And there may be parts that implicitly use floats such as heuristics to see if something is zero for simplification purposes. But my guess is that lots of stuff would work the same. > Which in turn makes me wonder what is your fixation with mathematica, since you > yourself so clearly do not like the numeric behavior, and other programs > actually support more closely the behavior you do like. Academic exercise? Interesting question. Public service? (To be sure I am not being paid by some competitor!). The online discussion of issues in computer algebra systems seems to have turned toward a handful of newsgroups or mailing lists. 3 or 4. This is one of them. The fact that it is specific to Mathematica is somewhat restrictive; on the other hand, having a moderator can be helpful at times. If someone raises a question about computer algebra systems in the context of Mathematica, and there seems to be a possibility that I can contribute to educating the poster and others reading the posting about that issue, then I sometimes chime in. Sometimes the questions are "why does Mathematica do X" and the answers from others look like "Because it does X" or "It has to do X" or "Everyone knows that X" or "you should ask Y". But my reaction might be more along the lines of "Mathematica was designed/programmed to do X, though it is not inevitable that a computer system should do this. I can understand why you might expect, from mathematical knowledge and intuition, that Mathematica should do something else, and it would be nice if it fulfilled your expectations, and here's how it might be changed to do that." Or something along those lines. > I'd be more charitably disposed, had you simply recognized from the > beginning that my example met your request. Ah, but perhaps you now understand my point -- you thought that your programs, using With [ {prec..}..] correctly modeled the behavior of other programs. I, on the other hand assumed quite the opposite, that you were inserting two different constants in a program, and then you contended that they were the same! I probably had as much concern for your sanity as you for mine. How could two textually different programs with different numbers in them be the same? I do see (now) what you were driving at. > This could be either by > explicit statement, or implicitly by just dropping the matter. Nailing > jello is not what I want to be doing just after having done my taxes. > Also it rather removes this from any semblence of scholarly > discussion--brings it closer to an "is too" "is not" level. That what > you really want in your discourse? > Nope. > Daniel Lichtblau > Wolfram Research RJF