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(core): don't simplify sqrt(x**2) if x is not positive #23653
Conversation
✅ Hi, I am the SymPy bot (v167). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.
Click here to see the pull request description that was parsed.
|
Benchmark results from GitHub Actions Lower numbers are good, higher numbers are bad. A ratio less than 1 Significantly changed benchmark results (PR vs master) Significantly changed benchmark results (master vs previous release) before after ratio
[77f1d79c] [3e51f99f]
<sympy-1.10.1^0>
+ 129±2ms 233±1ms 1.80 sum.TimeSum.time_doit
Full benchmark results can be found as artifacts in GitHub Actions |
Okay, tests have passed. I expected this change to be more problematic... I need to take a little time to work through the logic of The two test lines I've commented out also need more attention. I think they might be mathematically correct as tests but they test an evaluation that does not necessarily need to happen. I want to make sure I understand them but I don't currently see a need to try to fix them unless it can be done in a simple (and correct!) way. |
CC @smichr |
sympy/core/tests/test_power.py
Outdated
assert sqrt((p - p**2*I)**2) == p - p**2*I | ||
assert sqrt((p**2*I - p)**2) == p**2*I - p # XXX ok? | ||
#assert sqrt((p - p**2*I)**2) == p - p**2*I | ||
#assert sqrt((p**2*I - p)**2) == p**2*I - p # XXX ok? |
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.
These tests are clearly wrong. The left hand sides are obviously equal but the right hand sides are not.
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.
The first case seems correct. Is there a way to keep that and correct the 2nd case?
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.
I think it can be done like this:
diff --git a/sympy/core/power.py b/sympy/core/power.py
index 018ae5d..e46715c 100644
--- a/sympy/core/power.py
+++ b/sympy/core/power.py
@@ -470,6 +470,11 @@ def _n2(e):
s = 1 # floor = 0
elif re(b).is_extended_nonnegative and (abs(e) < 2) == True:
s = 1 # floor = 0
+ elif fuzzy_not(im(b).is_zero) and abs(e) == 2:
+ if re(b).is_extended_nonnegative:
+ s = 1
+ elif re(b).is_negative:
+ s = -1
elif _half(other):
s = exp(2*S.Pi*S.ImaginaryUnit*other*floor(
S.Half - e*arg(b)/(2*S.Pi)))
With that we have:
In [2]: p = symbols('p', positive=True)
In [3]: sqrt((p**2*I - p)**2)
Out[3]:
2
- ⅈ⋅p + p
In [4]: sqrt((p - p**2*I)**2)
Out[4]:
2
- ⅈ⋅p + p
I'm not sure that it's really a good idea though. This routine already has too many cases and is very complicated for ordinary evaluation. Really it would be better to handle this sort of thing in something like powsimp
.
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.
I don't have strong opinion. We can apply this when others complain.
42aa1f0
to
1ceeaf7
Compare
I think that the other cases in I started looking at improving This is ready for review. |
Looks good to me! |
Thanks both |
References to other Issues or PRs
This is an old bug dating back to #7638.
This was discovered during #22993 (#22993 (comment)).
Brief description of what is fixed or changed
This PR makes
Pow._eval_power
more conservative about simplifying(z**a)**b
toz**(a*b)
in the case of square rooting a square.On master we have:
It is
In [4]
that is incorrect as it does not give the principal root:The change here just removes a special case from
Pow._eval_power
:sympy/sympy/core/power.py
Lines 473 to 474 in e614ccb
The logic can the fall back to the more general code that can correctly handle this case:
sympy/sympy/core/power.py
Lines 475 to 481 in e614ccb
See the discussion in #7638 and certik/theoretical-physics#23 to understand the formula that is being used for simplification in this case.
Other comments
I expect this will break a few tests so I'm just putting it up first to see how it fares.
Release Notes
NO ENTRY