Closed mmaxs closed 3 years ago
Hi @mmaxs, thank you for the observation. I will try to analyze it asap.
Hi @mmaxs,
I fixed the issue. Could you please install the latest build https://github.com/mkulesh/microMathematics/raw/autobuild/autobuild/microMathematics-v2.20.2-debug.apk
and test how does it work?
Hi @mmaxs
I've just tested this and it doesn't settle the issue. Try i1 = [1, 2 .. 4.4], and it will be = [1 2 3 4.4] (missing of 4). I'm looking at the code and I think that you are overcomplicating the estimation of N. I suspect, it should be merely 1 + ceil((max - min) / delta). Doesn't it?
Unfortunately it is not too easy. From any reason I decided to always add the last point to the interval (i.e 4.4 will be always added at the and of the interval). In this case just ceil may have a rounding problem that results in an extra point at the end. This corner case is testes within the automatic test ts_interval.mmt from the app resources (that is only visible in developer mode).
Now i modified the calculation of the points number. It works now well both with my test cases as well with your example:
In this case just ceil may have a rounding problem that results in an extra point at the end.
Could you give an example? I don't see any issue with the formula 1 + ceil((max - min) / delta)
.
Look, with your scheme now:
i1 := [1, 2 .. 4.001] gives [1 2 3 4.001] -- missing of 4 (rounding effect by chance)
i2 := [1, 2 .. 5.001] gives [1 2 3 4 5 5.001] -- OK (rounding effect by chance)
i3 := [1, 2 .. 5.0001] gives [1 2 3 4 5.0001] -- missing of 5 (will always)
Hi @mmaxs,
this is an example where 1 + ceil gives us more points than necessary:
Now I used mode general approach. If you look into the document properties (menu "Document settings"), there is a parameter "Significant digits in result". I now used this parameter. The initial number of points N is now floor((max - min) / delta) . If the given maximum value is greater than (min + N delta) with respect to the precision defined by "Significant digits" parameter I will add this maximum value at the and. If the maximum value is equal to (min + N delta) with respect to this epsilon, no need to add this maximum. This approach solves both your initial and the last observation as well as satisfies all my automatic tests.
I think it is failry good solution.
Don't you think that in the conditional operator
(max > d1 && (max - d1) > eps * d1) ? N + 1 : N
instead of (max - d1) > eps * d1
should be just (max - d1) > eps
?
I mean the following situation when by just changing the beginning of an interval, we get a different number of points:
In the second case, the observed end of the interval is actually 10002.81, and the penultimate point of the exact value of 10002.8 is missing.
Hi @mmaxs
the use of the absolute deviation like (max - d1) > eps has a problem with small values like in this example:
If the absolute deviation (max - d1) > eps instead of relative (max - d1)/d1 > eps is used, both intervals will be shortened.
In your example it is enough to set "Significant digits" to 7 and you will have all points:
this is an example where 1 + ceil gives us more points than necessary:
But that interval with those parameters just should have 34 points. Any interval from
min
up tomax
withdelta=(max - min)/N
always has exactly N+1 points. And I see that in the ts_intervals.mmt tests the desired rows() value for it is M+1, that is 34.
So, for any user input for the interval in form of [min, min+delta, ..., max], it may be processed as point[0] = min point[1] = min + delta point[2] = min + 2 delta ... point[N] = min + N delta, where N = floor((max - min)/delta) and then, if point[N] < (max - epsilon), we must add one yet point[N+1] = max or else, if point[N] >= (max - epsilon), we, instead, should just set point[N] = max, as far as point[N] can't be > max due to the floor() function.
Another way to do all of that is point[0] = min point[1] = min + delta point[2] = min + 2 delta ... point[N] = min + N delta, where N = ceil((max - min)/delta) here, point[N] can't be < max due to the ceil() function (mathematically it can't, but in real calculations it can happen that it occurs to be < max, but in this case it's just a float point arithmetic effect), so we just always forcibly restrict (or fix) it to point[N] = max
Hi @mmaxs I totally agree with this theory. You are right, both approaches may be used and shall give perfect results. Your initial example b.interval1.mmt as well as all my other examples work with N=ceil((max - min)/delta) very well.
However, look at the test number 8 in ts_intervals.mmt again. It is a really special situation. dy = (y2-y1)/M = 5.9/33 is here a irrational number 0.1787878787878787... and it produces really huge numerical error when just ceil((max - min)/delta) is used:
N = 34
point[0]=-3.0
point[1]=-2.8212121212121213...
point[2]=-2.642424242424242...
...
point[33]=2.899999999999997
point[34]=2.9
i.e we have 35 points and visually the result looks like this:
Only this example and this test case is my problem. Mathematically it is correct, all 35 points are here, but due to numeric the last and previous points are equal. My idea was to skip the last point in this case and round up the previous point. I am sorry, in the screenshot 4 days ago I mistakable told about points number. In my code N is the index of the last point, i.e I have N+1 points. I mean here last index shall be 33 instead 34 with respect to this idea.
Of course we can say that my last really strange screenshot is a desired behavior and I just change adapt the test case accordingly. That do you think?
Now I have understood what you are talking about. I made some description of the problem: b.interval7.mmt.zip
Hi @mmaxs,
Все верно, вы очень точно описали мою проблему. Мне тоже кажется, что самая последняя версия хорошо соответствует подходу номер 2. Я тоже теперь вижу, в чем проблема с (max - d1)/d1 > eps. Действительно, деление разностной величины (max - d1) на абсолютную d1 не есть хорошо. Если использовать формулу для абсолютной погрешности (max - d1) > eps, то результат будет так себе:
Поэтому я уверен, что здесь нужно использовать относительную погрешность, а не абсолютную. И ваша идея (max - d1)/delta > eps мне очень понравилась, спасибо! Реализовал в последней версии именно этот вариант. Все мои тесты с этим вариантом работают хорошо. Тестируйте:
https://github.com/mkulesh/microMathematics/raw/autobuild/autobuild/microMathematics-v2.21.0-debug.apk
Я хочу сегодня-завтра выпустить эту версию, так как в ней есть два очень важных исправления. Предлагаю этот тикет закрыть, так как изначальная проблема исправлена, дальнейшую дискуссию продолжить по почте, и окончательный вариант войдет в следующий релиз.
Thank you.
Released in version 2.21.0
Example (look at![IMG_20201130_215638](https://user-images.githubusercontent.com/10092391/100652019-62f00300-3357-11eb-914b-94c16e1ced7c.JPG)
xcm
,xmm
,xfm
,xam
):b.interval1.mmt.zip