I find the terminology of open and closed intervals contradictory to their meaning. Does anyone know why they are described like this?
`Closed` makes me think shut or not-including - however it includes its endpoints. `Open` makes me think inclusive - yet does not include its endpoints.
Under this definition, 'closed' makes sense in the larger context, since in mathematics, if an operation is 'closed' on a set, that means that applying the operation to elements of the set always yields another element of the same set.
Open is a bit more awkward. A set O is 'open' if and only if the complement of O (i.e. the set of all points not in O) is closed. So open is kind of the opposite of closed, hence the convention. Of course, it isn't really the opposite of closed, since there are sets which are neither closed nor open.
tt;dr (too technical; didn't read) in maths, 'closed' usually means 'I can do stuff inside this set without falling out of it'. In the case of intervals, the 'stuff' in question is taking a limit of a convergent sequence.
With a closed interval it eventually return a bound instead of getting smaller/larger - continuing.
This no doubt sounds strange, but it surely comes down to the slightly odd behavior of real numbers. In an open interval like (0, 1), there is no single real number which is less than one but is greater than all other real numbers less than one. (Proof by Cantor's diagonal: write out a list of all such numbers and you can always construct another which wasn't on the list, even when the list is infinite.) In contrast, the closed interval [0, 1] has a definite maximum element, the number 1.
This seems like a good example of poor UX in mathematics; the terms are too similar and can only be learned by memorization, the notations likewise. Good luck changing it though; Wikipedia informs me that there are no less than two ISO standards codifying it.
There is a perfectly clear notation in the Wikipedia page, however: (a,b) = {x∈ℝ|a<x<b}; [a,b] = {x∈ℝ|a≤x≤b}
The rational numbers are like this too.
All the rational numbers between 0 and 1 also increase arbitrarily close to 1 with no largest element. You can prove this by simple contradiction: For every rational number x < 1, there is another rational number y = (x+1)/2 with x < y < 1. So the set of rational numbers less than 1 also has no largest element.
Actually real numbers can be defined (axiomatized) in terms of the least upper bound property -- every set of real numbers that's bounded above has a least upper bound. So you could actually have a set S of rational numbers that gets arbitrarily close to something like sqrt(2) from below. S then has no rational least upper bound -- for every rational number x greater than or equal to every element of S, there is another rational number y greater than or equal to every element of S but smaller than x.
Note that a set of real numbers need not contain its upper bound -- as you noted, a bounded open interval doesn't contain its upper bound.
Also, any notation will have to be learned. Concise ones a bit more, but there is nothing one can do about that.
And that perfectly clear notation requires you to learn quite a bit by memorization, such as the meaning of those {} brackets, the |, and the symbols ∈ and ℝ.
Finally, you don't need Cantor's diagonalization for a proof. It is easy(1) to show that, for any real x<1, x+(1-x)/2 is real, less than one, and strictly greater than x.
Alternatively, assuming 0<x<1, write x in decimal, and increase the first digit less than nine by one to get a larger real less than one. There is such a digit because 0.9999999… is not less than one.
(1) depending on how deep you want to descend into the foundations of mathematics.
To take your thinking a bit further the interval is "shut" precisely because it's closed exactly at that point. And the interval is thrown "open" by not including the point.
BTW; Rudin's classic text (1) covers the fascinating topic of neighborhoods which builds on the concept of intervals. It took me a while to completely understand the concept but after that understanding limits was relatively easier; even otherwise "neighborhood" as a concept is interesting in itself.
[1] http://www.math.boun.edu.tr/instructors/ozturk/eskiders/guz1...
Thanks for everyone's input. I think I have a clear understanding of the open/closed paradigm now.
for ( ; ; )
or: while ( true )
etc.You just know you're setting yourself up for undocumented bugs later.
I've been known to build "escape" vars into these like:
int attempts = 1000;
for(;attempts > 0;attempts--) {
** DO SOMETHING **
}
if (attempts <= 0) {
** BAIL ***
}
Where 1000 or whatever number is a reasonable estimate of the function's need to loop x 10 or etc.1. Some initialization (optional). 2. Some stuff you do each iteration (optional). 3. Check the exit condition and exit the loop (optional). 4. Some stuff you do each iteration (optional).
"while" loops nicely handle the case where 2 is empty. "do while" loops handle 4 being empty. "for" loops handle both 2 and 4 being non-empty but only really accommodate 4 being a single expression.
For any other case where 2 is non-empty and 4 is more than a single expression, I just use a "while (true)" with an "if (...) break;" in the body.
[0] Or utterly catastrophic. Think embedded system with limited debugging facilities. This kind of bug could manifest as the system completely locking up, and take much, much longer to track down than a "infinite loop detected!" message in an error log.
1) Algorithm FT says:
1. Generate u. Store the first bit of u
as a sign s (s=0 if u<1/2, s=1 if u>=1/2).
and yet the C code implements if ( u <= 0.5 ) s = 0.0;
else s = 1.0;
2) I can't be sure of the following w/o access to doc. But i4_uni() says a uniform distribution over (1, 2147483562)
which, offhand, is suspicious. A distribution over positive integers would probably want to use all available values in a 32-bit signed int, so it would most likely end at 2^31 -1 which is 2147483647, and not the value given.You could use that argument about any of the random numbers that your rng returns. "Hey, 0.023 is infinitesimally unlikely to occur, so let's exclude that as well".
Generally when I use a real-valued rng, the numbers generated are meant to be 'representative' of what I should get from the distribution. And when I get e.g. 0.023, it kind-of means "0.023 and/or numbers near to 0.023". If I excluded 0.023 from the possible results of the rng, then I would have a 'hole' in my distribution 'in the region of' 0.023.
Maybe what you want is to go from the possible rnds:
0.000, 0.001, 0.002, 0.003, ... , 0.999
to:
0.0005, 0.0015, 0.0025, ... , 0.9995
whereas with your suggestion, you are under-representing the boundary numbers near to 0 and/or near to 1. Generally not a problem I guess, but what you are doing is, imo, 'wrong in theory', even though your high-precision floats will probably cover it up ok in almost all cases.
I agree with you about 0 and 1 causing problems when they are fed into other functions - e.g. generating Gaussian rngs by using InverseCumulativeGaussian(0.0) - a bug I wasted some time hunting down in my company's rng library. My view was that the developer who wrote the library did not understand the maths of what he was doing, rather than that the 0to1 random number generator was at fault.
If you'll pardon me pulling out my soapbox for a moment, this kind of bug would be less common if the "programmers don't need math" attitude was not a successful meme in our culture. The notion of "between zero and one" may seem straghtforward and obvious, but is actually ambiguous. Perhaps, given the number of distinct floating point values that can be represented in the interval (0,1), it would hardly seem to matter what interpretation of "between zero and one" is used. But in mathematics you will never see such terminology used without a qualifying statement that clarifies* the meaning.
*E.g. "between 0 and 1, inclusive", "on the closed interval bounded by 0 and 1", "[0,1]", etc.
More stories like that?
I've never used ranlib; I hope the documentation can be cleaned up at least. On the other hand, anyone who has read A Deepness in the Sky will surely feel that it is unlikely in the long term.
I wonder about the resolution: was snorm() reimplemented correctly, or was an RNG with the 'wrong' interval supplied?