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
_solve
and _solve_system
: return list of dictionaries
#23877
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. Your release notes are in good order. Here is what the release notes will look like:
This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.12. Click here to see the pull request description that was parsed.
Update The release notes on the wiki have been updated. |
I haven't reviewed this in detail but from a glance it looks like a nice improvement. |
_solve
and _solve_system
return lists of dictionaries_solve
and _solve_system
: return list of dictionaries
dee0d38
to
d39448b
Compare
124c430
to
6cea462
Compare
OK, then I have nothing more planned for this PR. |
e78f987
to
bee6426
Compare
>>> tsolve(3**(2*x + 5) - 4, x) | ||
[-5/2 + log(2)/log(3), (-5*log(3)/2 + log(2) + I*pi)/log(3)] | ||
>>> set(tsolve(3**(2*x + 5) - 4, x)) | ||
{(-5*log(3)/2 + log(2) + I*pi)/log(3), -5/2 + log(2)/log(3)} |
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.
Is this doctest reliable?
I would have expected the set to print in different orders on different runs.
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 test seems to work okay when I run it several times. Maybe that's because the SymPy printer makes the order deterministic...
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.
It is written to be reliable since {1,2}=={2,1}
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.
Yes, but with standard Python repr printing the order when printed is non-deterministic and doctest matches the text output directly (rather than doing any set comparison).
I think this looks good. More cleanup is still needed e.g. to break |
Let's get this in. |
Thanks for the help. We're making progress. |
After merging this the slow2 test failed on the master branch: It seems that a slow test in I might have seen that failure recently in which case maybe it isn't related to this PR but since it is |
The failure in #23832 is different:
|
I can confirm that the following fails non-deterministically:
I just tried repeatedly and it passed 3 times before failing on the 4th run:
|
The following script returns nondeterministic output: from sympy import *
x = symbols('x')
print(solve(3**cos(x) - cos(x)**3)) Running 10 times: $ for i in `seq 1 10`; do python t.py; done
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[2*pi - acos(3), 2*pi - acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[2*pi - acos(3), 2*pi - acos(-3*LambertW(-log(3)/3)/log(3))]
[2*pi - acos(3), 2*pi - acos(-3*LambertW(-log(3)/3)/log(3))] Checking out a commit shortly before this PR it seems to be deterministic: $ git checkout 6fd8df361985e2c3bfdfb4767c32f0e5e5ccd
$ for i in `seq 1 10`; do python t.py; done
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))]
[acos(3), acos(-3*LambertW(-log(3)/3)/log(3))] |
Setting the hash seed does not make the output deterministic. |
sols.append(cv_inv.subs(t, sol)) | ||
result = list(ordered(sols)) | ||
cv_inv = _vsolve(t - f1, symbol, **flags)[0] | ||
result = [{symbol: cv_inv.subs(sol)} for sol in cv_sols] |
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.
Here _vsolve
returns a list [acos(_t), -acos(_t) + 2*pi]
but the ordering of this list is nondeterministic. The line above arbitrarily selects the first element of this list.
@smichr what should be the fix for the test that fails as a result of this PR? It's showing up as a failure in CI about 50% of the time. |
see #23918 |
References to other Issues or PRs
Brief description of what is fixed or changed
This is mostly an internal clean-up of
solve
to work with lists of dictionaries from_solve
and_solve_system
while maintaining legacy output.Other comments
A solution is only made canonical by solve;
_solve
,_solve_system
and_tsolve
no longer are guaranteed to return a canonical list. This seems appropriate for helper functions.The bare dictionary return value will only occur when a single equation is being solved for undetermined coefficients
or when n-linear-equations in n-unknowns are being solved and manual is not True
Release Notes
solve
now only returns a bare dictionary when 1) solving a single expression (not in a list) for undetermined coefficients or 2) for a list of n linear equations in n unknowns when manual!=Truesolve
to solve for undetermined coefficients, the solution is no longer simplified (because it is detected as having been solved as a polynomial system; and such systems are not simplified)