Re: [boost] boost interval arithmetic
(please keep the conversation on the list) On Wed, 14 Jan 2015, Павел Кудан wrote:
Dear Marc,
Thank you for your answer, I also tried to contact Mr.Gubenko, have no information about other maintainers. Please, excuse my bad English, I will try to explain in more detail, please, ask if something will be uncertain.
I thought the maintainers would be the 3 authors.
Boost interval library was planned as extension of mathematical functions on float/double/double long or other singe numeric values to operations on intervals. The problem is that intervals have some specific. For example, if float value can be either > either < or = some other float value (statement ! (a>b) == (a <= b) is always true), for intervals it is not correct. Intervals can also overlap. That means that it is not possible for pair of overlapping intervals to say certainly which of them are greater than other. It is the intermediate situation, which is impossible with original single float values.
And boost interval class has comparison operators and user can expect that they will behave in similar way with usual float comparison operators.
For that reason, the behaviour of that comparison operators was made changeable and depends on some kind of policy, defined by user. Default behaviour is to throw exception when such intermediate situation (not possible for single float values) takes place.
That was very wise solution, especially useful in very probable case, when some programmer will try to adapt some existing code with float calculation just changing type of value to boost interval. He will get exception in than exceptional situation - when usual float comparison operator is not applicable any more.
That is OK.
But as well boost interval class defines mathematical functions and operators. And user can expect that they also will behave similarly to usual float comparison operators. But great disappointment and multiple possible errors which is hard to locate is waiting for him here. Because it is not so. Arithmetic operators behave in completely different manner.
Let's look on of most basic operator =/ and see what it is doing.
But before let's see what is division of intervals and what is it's result.
Boost interval class has two function - division_part1() and division_part2(). It is correct as when you divide one interval with another, the result will be single interval or a pair of intervals. The last situation takes place when in statement A / B, interval B cross a zero. That is not normal for intervals to have a pair of intervals as a result of division, but it is exceptional for single float numeric division.
Now let's get back to /= operator and watch what he will do in such case.
Let A = [1,2] and B = [-1, 1]
and let's see what we will get after A /= B and what we should get.
The true result of division in that case will be a union of pair of intervals [-infinity, -1] and [2, -infinity]
Actually, [-inf,-1][1,+inf]
Interval /= operator, naturally, must return one interval. It is, obviously, impossible in this case - to return one of two. Again intermediate situation, not applicable to single float calculations. Again, throwing exception must be a result to let user know that he does not know what he are really doing. The same behaviour, as comparison operators. But it is not so.
Instead of such natural behaviour, /= operator of boost interval class are doing impossible thing. It silently decides for itself which one of two parts of whole result to return and kill another part of whole solution somewhere under the scene.
The result of A /= B will be [-infinity, -1]. Not correct result - as it is not complete. One of to parts is missing.
Did you really observe that? If so, it is a bug. [1,2]/[-1,1] is supposed to give [-inf,inf] (and it does indeed, in my tests), which certainly contains the right value ;-) If you have a testcase that shows differently, it would be good to open a bug report on trac.
Very very bad operator behaviour. User get not correct result and even does not know that it is so. It will be hard to find when this error is located, and when it will be done, library user will not think that he should know better what he are doing and learn some basics of interval arithmetic - no, he will accuse boost interval as part and boost as whole for bugs in libraries implementation. U nfairly , of course, but who cares.
To correct it, at least, arithmetic operators and functions of interval class must behave similarly to comparison operators - throw exception in situations, not applicable for single float calculations.
That is what I meant when said: "The difference in behaviour of comparison operators and basic arithmetic operators looks as probable misconception."
I know, it is hard to understand, especially because bad English, but I hope it is important and hope it will help.
-- Marc Glisse
Excuse me for not understanding what you mean...
Wed, 14 Jan 2015 15:08:22 +0100 (CET) от Marc Glisse
(please keep the conversation on the list)
On Wed, 14 Jan 2015, Павел Кудан wrote:
Dear Marc,
Thank you for your answer, I also tried to contact Mr.Gubenko, have no information about other maintainers. Please, excuse my bad English, I will try to explain in more detail, please, ask if something will be uncertain.
I thought the maintainers would be the 3 authors.
Boost interval library was planned as extension of mathematical functions on float/double/double long or other singe numeric values to operations on intervals. The problem is that intervals have some specific. For example, if float value can be either > either < or = some other float value (statement ! (a>b) == (a <= b) is always true), for intervals it is not correct. Intervals can also overlap. That means that it is not possible for pair of overlapping intervals to say certainly which of them are greater than other. It is the intermediate situation, which is impossible with original single float values.
And boost interval class has comparison operators and user can expect that they will behave in similar way with usual float comparison operators.
For that reason, the behaviour of that comparison operators was made changeable and depends on some kind of policy, defined by user. Default behaviour is to throw exception when such intermediate situation (not possible for single float values) takes place.
That was very wise solution, especially useful in very probable case, when some programmer will try to adapt some existing code with float calculation just changing type of value to boost interval. He will get exception in than exceptional situation - when usual float comparison operator is not applicable any more.
That is OK.
But as well boost interval class defines mathematical functions and operators. And user can expect that they also will behave similarly to usual float comparison operators. But great disappointment and multiple possible errors which is hard to locate is waiting for him here. Because it is not so. Arithmetic operators behave in completely different manner.
Let's look on of most basic operator =/ and see what it is doing.
But before let's see what is division of intervals and what is it's result.
Boost interval class has two function - division_part1() and division_part2(). It is correct as when you divide one interval with another, the result will be single interval or a pair of intervals. The last situation takes place when in statement A / B, interval B cross a zero. That is not normal for intervals to have a pair of intervals as a result of division, but it is exceptional for single float numeric division.
Now let's get back to /= operator and watch what he will do in such case.
Let A = [1,2] and B = [-1, 1]
and let's see what we will get after A /= B and what we should get.
The true result of division in that case will be a union of pair of intervals [-infinity, -1] and [2, -infinity]
Actually, [-inf,-1][1,+inf]
Interval /= operator, naturally, must return one interval. It is, obviously, impossible in this case - to return one of two. Again intermediate situation, not applicable to single float calculations. Again, throwing exception must be a result to let user know that he does not know what he are really doing. The same behaviour, as comparison operators. But it is not so.
Instead of such natural behaviour, /= operator of boost interval class are doing impossible thing. It silently decides for itself which one of two parts of whole result to return and kill another part of whole solution somewhere under the scene.
The result of A /= B will be [-infinity, -1]. Not correct result - as it is not complete. One of to parts is missing.
Did you really observe that? If so, it is a bug. [1,2]/[-1,1] is supposed to give [-inf,inf] (and it does indeed, in my tests), which certainly contains the right value ;-)
If you have a testcase that shows differently, it would be good to open a bug report on trac.
Very very bad operator behaviour. User get not correct result and even does not know that it is so. It will be hard to find when this error is located, and when it will be done, library user will not think that he should know better what he are doing and learn some basics of interval arithmetic - no, he will accuse boost interval as part and boost as whole for bugs in libraries implementation. U nfairly , of course, but who cares.
To correct it, at least, arithmetic operators and functions of interval class must behave similarly to comparison operators - throw exception in situations, not applicable for single float calculations.
That is what I meant when said: "The difference in behaviour of comparison operators and basic arithmetic operators looks as probable misconception."
I know, it is hard to understand, especially because bad English, but I hope it is important and hope it will help.
-- Marc Glisse
P. Coodan
But as well boost interval class defines mathematical functions and operators. And user can expect that they also will behave similarly to usual float comparison operators. But great disappointment and multiple possible errors which is hard to locate is waiting for him here. Because it is not so. Arithmetic operators behave in completely different manner.
Let's look on of most basic operator =/ and see what it is doing.
But before let's see what is division of intervals and what is it's result.
Boost interval class has two function - division_part1() and division_part2(). It is correct as when you divide one interval with another, the result will be single interval or a pair of intervals. The last situation takes place when in statement A / B, interval B cross a zero. That is not normal for intervals to have a pair of intervals as a result of division, but it is exceptional for single float numeric division.
Now let's get back to /= operator and watch what he will do in such case.
Let A = [1,2] and B = [-1, 1]
and let's see what we will get after A /= B and what we should get.
The true result of division in that case will be a union of pair of intervals [-infinity, -1] and [2, -infinity]
Actually, [-inf,-1][1,+inf]
Interval /= operator, naturally, must return one interval. It is, obviously, impossible in this case - to return one of two. Again intermediate situation, not applicable to single float calculations. Again, throwing exception must be a result to let user know that he does not know what he are really doing. The same behaviour, as comparison operators. But it is not so.
Instead of such natural behaviour, /= operator of boost interval class are doing impossible thing. It silently decides for itself which one of two parts of whole result to return and kill another part of whole solution somewhere under the scene.
The result of A /= B will be [-infinity, -1]. Not correct result - as it is not complete. One of to parts is missing.
Did you really observe that? If so, it is a bug. [1,2]/[-1,1] is supposed to give [-inf,inf] (and it does indeed, in my tests), which certainly contains the right value ;-)
If you have a testcase that shows differently, it would be good to open a bug report on trac.
To certainly contain right value and to be write value are cernainly different things, are not? :)) By the way, if you get [-inf, inf] in that case, then boost interval class has not only misconception but also a bag. Its result should be [-inf, 1] according to documentation. Let's see presentation about boost interval and interval arithmetic. https://www.lri.fr/~melquion/doc/03-rnc5-expose.pdf On page 11: Functions can also be used to compute a pair of intervals: [1, 2] ÷ [−1, 1] = [−∞, −1] ∪ [1, +∞]. (that is not boost interval operator / yet, it is basic arithmetic operation for interval. That is what should be a result) also, on page 5: [a, b] × [c, d] = [min(ac, bc, ad, bd), max(ac, bc, ad, bd)], [a, b] ÷ [c, d] = [a, b] × [1 ÷ d, 1 ÷ c] if 0 NOT ∈ [c, d] (that is not boost interval operator / yet, but it is the way its result is calculated when zero is not inside of [c, d] interval (by the way, typo here - must be 'if 0 NOT ∈ (c, d)). And here official boost interval documentation http://www.boost.org/doc/libs/1_37_0/libs/numeric/interval/doc/interval.htm The operators / and /= will try to produce an empty interval if the denominator is exactly zero. If the denominator contains zero (but not only zero), the result will be the smallest interval containing the set of division results; so one of its bound will be infinite, but it may not be the whole interval. So, official documented result of / operator for that case is [-inf, 1] as it is smallest interval (the result of division_part1() function of boost interval class). And this result is not correct as it is not full. If you get [-inf, inf] result in real test, it means that boost interval class has not only misconception, but also a bag, as it also conflict with own misconception :)))
participants (2)
-
Marc Glisse
-
Павел Кудан