Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

changed max_precision for real #18

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

changed max_precision for real #18

wants to merge 2 commits into from

Conversation

SagnikDey92
Copy link
Contributor

@SagnikDey92 SagnikDey92 commented Apr 9, 2019

Currently only the greater than and less than operator tests don't pass. They will need similar changes as in the == operator test. That is: remove precision exception checks where a comparison is possible and just check the functioning of < operator. I also added a few tests under My Tests section in the real eq operator test. I didn't make the changes in the <, > operator tests as I wanted to confirm whether this is correct. If yes, I'll update once again. All other tests except these two are still passing. These two are the real_lower_than_operator_test and real_greater_than_operator_test.

Edit: Okay, I was being lazy not updating the greater than and less than tests. I've now changed them for the travis build to pass.

@SagnikDey92 SagnikDey92 closed this Apr 9, 2019
@SagnikDey92 SagnikDey92 reopened this Apr 9, 2019
Copy link
Collaborator

@Laouen Laouen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've put some comments, there is a general conceptual error that is spread in the code and tests in general. I didn't comment on all the errors because most of them are the same error and it makes no point to comment the same all over the code.

The main problem is that a maximum precision is set to determine until where the library will iterate the precision in order to get more accurate approximation intervals that could possibly answer the operator question ( ==, <, >, etc). But if the maximum precision is reached before the question is answered, then there should be a precision exception because we have approximation intervals that are not small enough to decide.

@@ -204,7 +204,9 @@ namespace boost {
* @param exponent - an integer representing the number exponent.
*/
explicit real_algorithm(int (*get_nth_digit)(unsigned int), int exponent)
: _get_nth_digit(get_nth_digit), _exponent(exponent), _positive(true) {}
: _get_nth_digit(get_nth_digit), _exponent(exponent), _positive(true) {
set_maximum_precision(15);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this max precision hardcoded with a 15? It should be the value of boost::real::real::maximum_precision which is the default max precision.

Suggested change
set_maximum_precision(15);
set_maximum_precision(boost::real::real::maximum_precision);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this max precision hardcoded with a 15? It should be the value of boost::real::real::maximum_precision which is the default max precision.

Suggested change
set_maximum_precision(15);
set_maximum_precision(boost::real::real::maximum_precision);

maximum_precision is an uninitialised variable currently and seems to take the value 10. Also, that hardcoded 15 is for algorithm numbers. I don't know what to use as its precision so I just chose 15. Please suggest default max precision for algorithm numbers which might have infinite precision. Or what show max_precision be initialised with for algorithm numbers?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boost::real::real::maximum_precision and boost::real::real_algorithm::maximum_precision are global variables the user must set at the start of their code to specify the global maximum precision that is ever allowed. If you check the tests, you can notice in test/include/test_helpers.hpp in lines 9 and 10 that those variables are set in 10 and that is why they have that value (It is never hardcoded). With no exceptions, these variable is used as the max precision ever accepted and even for explicit numbers that have more digits than this maximum precision, they will throw a precision_exception.

The max precision is used to allow having some control in the algorithm memory and time complexities.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh no...
I never noticed the initialisations in test_helpers which has led to a lot of confusion for me as I couldn't figure out why the precision cap was at 10...
Now it seems like there wasn't any issue in the first place. The precision error I thought was a mistake was due to this max_precision of 10. And then the algorithm precision can just be kept as the max_precision set in test_helpers then.

@@ -224,7 +226,9 @@ namespace boost {
bool positive)
: _get_nth_digit(get_nth_digit),
_exponent(exponent),
_positive(positive) {}
_positive(positive) {
set_maximum_precision(15);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
set_maximum_precision(15);
set_maximum_precision(boost::real::real::maximum_precision);

@@ -149,7 +149,7 @@ TEST_CASE("Iterator cend") {

SECTION("Iterate until the maximum set precision returns the end of the iterator") {

for(int i = 0; i < 9; i++) {
for(int i = 0; i < 14; i++) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for(int i = 0; i < 14; i++) {
for(int i = 0; i < boost::real::real::maximum_precision-1; i++) {

boost::real::real b(one_one_one, 1);

CHECK_THROWS_AS(a == b, boost::real::precision_exception);
CHECK_FALSE(a == b);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should throw a precision exception because b is an algorithmic number, the full precision of an algorithmic number is never reached (i.e b.lowe_bound() < b.upper_bound() is always true) and thus, you can never know if a == b.

Algorithmic numbers are thought as numbers with infinity digit size; b could be 1.110000000...........000001 and you will never know it because the max precision is reached before you get there. Even if you iterate enough to reach the last "1", there could be more non zero digits after that and you don't know until when you must iterate. This is known as an undecidable problem. You can now if a != b (if you iterate enough) but no if a == b.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, I originally thought one_one_one is actually 1.11111111. I'll make the change. This explains what I noticed and commented earlier in the code that 1.111 works but 1.11 doesn't. Cause b is 1.1100000...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, b = 1.11000...

@@ -162,17 +162,17 @@ TEST_CASE("Operator ==") {

SECTION("With precision exception") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read the section name "With precision exception" these tests should all through a precision exception.

There is a problem with your modifications, because algorithmic numbers can never be fully known and therefore, by definition of "fully known" (i.e. the upper and lower bounds of the approximation interval are equals) these numbers can never be compared with == and return a true. We are able to say that they are different ( != operator ) but not that they are equal ( == operator ).

The problem is that once you reach the maximum precision, you just asume you know the full number. For the numbers in the test, this happens because we constructed those numbers and we know that, but this is not something the Boost:Real library knows and the precision exception should be thrown.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could I not just add a check for the EXPLICIT case? And for algorithm numbers, what precision to use for comparison as it can be arbitrarily high if not specified by set_precision

}
}

SECTION("My Tests") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name can't be "My test". The name must be descriptive about what the section is testing. This is an open source code that more people will work on it and not a private code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry... I intended that as a temporary but forgot to remove it.

boost::real::real b(one_one_one, 1);

CHECK_THROWS_AS(a > b, boost::real::precision_exception);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of the test is to have a precision error, that is why "a = 1.11" that is equal to "b", but because "b" is an algorithmic number, then, we can't know whether "a > b" or not.

If you change a to 1.111 you know that a is greater than b because you know that 1.111.... > 1.110.... for all the possible values of the remaining infinity lower digits of "b".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, same as before. I thought one_one_one is 1.111111...
Will fix

@Laouen Laouen self-assigned this Apr 15, 2019
@sdavtaker
Copy link
Contributor

Hi,
Can you resubmit this PR in https://github.com/BoostGSoC19/Real and close it here?
This Repository is frozen now that repository for 2019 exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants