-
Notifications
You must be signed in to change notification settings - Fork 278
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
Fix for UnivariatePolynomial::__eq__ #847
Conversation
I wonder if we should just make sure when the polynomial is created, that it is always in a canonical form, so that then you can literally just compare the dictionaries? @isuruf what do you think? |
Yes, that should be easier. |
@isuruf So, something like this? If we do it this way, we should probably add code to is_canonical to check that the dictionary contains no terms with zero coefficients. This would make the canonical form of the polynomial "0" be a polynomial with an empty dictionary, which would require changing some code in the tester and some of the code in printer.cpp. |
@myluszczak, exactly. I think this looks good. |
/*for(auto itter = dict.begin(); itter != dict.end(); itter++){ | ||
if(0 == itter->second) | ||
return false; | ||
}*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can uncomment this code
There are currently 3 ways of creating a polynomial.
Instead of that we can do,
Only method 2 and 3 will call 1 and all other references to 1 will be replaced by 3. |
@isuruf I think that's a good plan, and I'll put that in the next commit. Thanks for the head's up on the redundant checks in get_args; I missed that when I copied the code form the original implementation of from_dict. |
In the above commit I've done what I though would implement isuruf's idea above, however on my machine compilation stops when linking test_arit with the error message
Since it's late, I'm going to shower and go to bed. |
return make_rcp<const UnivariatePolynomial>(var, (--(d.end()))->first, std::move(d)); | ||
} | ||
|
||
RCP<const UnivariatePolynomial> from_vec(const RCP<const Symbol> &var, const std::vector<integer_class> &v){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change the name to UnivariatePolynomial::from_vec
Can you rebase on top of master and fix merge conflicts? @chenchfort should be able to help you out. If not let me know if you need my help. |
@myluszczak Are you developing in debug mode? |
@shivamvats Not in general, no. I just compiled and tested it in debug mode, though, and it still works on my machine. The main difference between the behavior of release and debug modes is that in debug mode we call the SYMENGINE_ASSERTs, right? |
{{var, integer(d.begin()->first)}}); | ||
for(auto itter = d.begin(); itter != d.end(); itter++){ | ||
if(integer_class(0) == itter->second) | ||
d.erase(itter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably what is causing the segfault. If you delete while iterating, the iterator becomes invalid.
@isuruf So, a better implementation would be to create a new dictionary and only add to that if the coefficient is nonzero? |
} | ||
if(dict_.empty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Space after if
+1. If you can rebase on top of master, we can get this merged |
I'm a bit new to git. That'd be |
Yes |
You'll need to resolve the conflict. |
@chenchfort wait, which conflict? |
Have you rebased? Did it complain about conflicts? |
I'm rebasing now, and it is complaining about conflicts currently. I am currently resolving them. |
@chenchfort Alright, so I finished the rebase, but now git refuses to push ``To https://github.com/chenchfort/symengine --resolved |
Ok force pushed. Looks good. |
Closed in favour of #855 |
The current implementation of
UnivariatePolynomial::__eq__
checks if the dictionaries of the two polynomials are exactly equal, and will return false if comparing polynomials with the dictionaries{{0,0},{1,2}}
and{{1,2}}
representing0 + 2x
and2x
respectively. Since addition does not remove the entries of a dictionary corresponding to terms that have zero coefficients, this can lead to a situation where SymEngine tells us that(x+1) + (x-1) != 2x
, as shown below.test.zip
My implementation replaces the call to
map_uint_mpz_eq
with a call topoly_dict_map_uint_mpz_eq
, which returns true if two dictionaries are the same (excluding those entries where the coefficient is zero.)