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
Polys: Refine dup_clear_denoms function and update tests #26180
Conversation
…module, focusing on enhancing its efficiency and reliability when dealing with exact domains. The adjustments ensure that the function more accurately clears denominators, especially in scenarios involving symbolic expressions and rational numbers. Changes made include: - Fine-tuning the logic for handling denominators to ensure robust performance across a variety of use cases. - Streamlining the conversion process to guarantee that expressions are correctly converted to the target domain when requested. The primary aim of these modifications was to address feedback and improve the function's handling of symbolic and rational expressions, thereby increasing the utility and reliability of polynomial operations within Sympy. Updated tests reflect these changes by focusing on: - Verifying the accurate clearing of denominators in exact domains. - Ensuring the `convert` flag functions as intended across different scenarios. While initial considerations included enhancements for inexact domain handling, this version concentrates on exact domains to solidify the foundation of `dup_clear_denoms`. Future work may revisit inexact domain improvements. Fixes issue: sympy#26176 (sympy#26176)
✅ Hi, I am the SymPy bot. 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.13. Click here to see the pull request description that was parsed.
Update The release notes on the wiki have been updated. |
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) | Change | Before [a00718ba] | After [d5563740] | Ratio | Benchmark (Parameter) |
|----------|----------------------|---------------------|---------|----------------------------------------------------------------------|
| - | 68.3±0.6ms | 44.0±0.3ms | 0.64 | integrate.TimeIntegrationRisch02.time_doit(10) |
| - | 68.6±1ms | 43.2±0.2ms | 0.63 | integrate.TimeIntegrationRisch02.time_doit_risch(10) |
| + | 18.6±0.4μs | 29.7±0.4μs | 1.6 | integrate.TimeIntegrationRisch03.time_doit(1) |
| - | 5.38±0.04ms | 2.84±0.03ms | 0.53 | logic.LogicSuite.time_load_file |
| - | 73.5±0.4ms | 28.3±0.4ms | 0.38 | polys.TimeGCD_GaussInt.time_op(1, 'dense') |
| - | 25.8±0.04ms | 16.7±0.06ms | 0.65 | polys.TimeGCD_GaussInt.time_op(1, 'expr') |
| - | 73.6±0.2ms | 28.6±0.2ms | 0.39 | polys.TimeGCD_GaussInt.time_op(1, 'sparse') |
| - | 254±2ms | 123±1ms | 0.48 | polys.TimeGCD_GaussInt.time_op(2, 'dense') |
| - | 254±1ms | 123±1ms | 0.48 | polys.TimeGCD_GaussInt.time_op(2, 'sparse') |
| - | 647±3ms | 366±0.9ms | 0.57 | polys.TimeGCD_GaussInt.time_op(3, 'dense') |
| - | 653±3ms | 367±2ms | 0.56 | polys.TimeGCD_GaussInt.time_op(3, 'sparse') |
| - | 497±2μs | 282±2μs | 0.57 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(1, 'dense') |
| - | 1.81±0.01ms | 1.05±0.01ms | 0.58 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(2, 'dense') |
| - | 5.83±0.02ms | 3.09±0.02ms | 0.53 | polys.TimeGCD_LinearDenseQuadraticGCD.time_op(3, 'dense') |
| - | 449±2μs | 227±2μs | 0.51 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(1, 'dense') |
| - | 1.48±0.01ms | 669±3μs | 0.45 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(2, 'dense') |
| - | 4.85±0.02ms | 1.66±0ms | 0.34 | polys.TimeGCD_QuadraticNonMonicGCD.time_op(3, 'dense') |
| - | 381±2μs | 205±0.7μs | 0.54 | polys.TimeGCD_SparseGCDHighDegree.time_op(1, 'dense') |
| - | 2.45±0.03ms | 1.24±0ms | 0.5 | polys.TimeGCD_SparseGCDHighDegree.time_op(3, 'dense') |
| - | 10.0±0.05ms | 4.33±0.04ms | 0.43 | polys.TimeGCD_SparseGCDHighDegree.time_op(5, 'dense') |
| - | 362±1μs | 171±1μs | 0.47 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(1, 'dense') |
| - | 2.48±0.01ms | 884±10μs | 0.36 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(3, 'dense') |
| - | 9.59±0.05ms | 2.68±0.01ms | 0.28 | polys.TimeGCD_SparseNonMonicQuadratic.time_op(5, 'dense') |
| - | 1.04±0ms | 427±6μs | 0.41 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(3, 'dense') |
| - | 1.73±0.01ms | 503±2μs | 0.29 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(3, 'sparse') |
| - | 5.88±0.03ms | 1.79±0.02ms | 0.3 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(5, 'dense') |
| - | 8.44±0.02ms | 1.48±0.01ms | 0.18 | polys.TimePREM_LinearDenseQuadraticGCD.time_op(5, 'sparse') |
| - | 284±0.8μs | 64.3±0.2μs | 0.23 | polys.TimePREM_QuadraticNonMonicGCD.time_op(1, 'sparse') |
| - | 3.38±0.04ms | 389±2μs | 0.11 | polys.TimePREM_QuadraticNonMonicGCD.time_op(3, 'dense') |
| - | 4.00±0.04ms | 279±1μs | 0.07 | polys.TimePREM_QuadraticNonMonicGCD.time_op(3, 'sparse') |
| - | 7.15±0.07ms | 1.24±0.01ms | 0.17 | polys.TimePREM_QuadraticNonMonicGCD.time_op(5, 'dense') |
| - | 8.75±0.03ms | 835±3μs | 0.1 | polys.TimePREM_QuadraticNonMonicGCD.time_op(5, 'sparse') |
| - | 5.06±0.01ms | 2.97±0.01ms | 0.59 | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(2, 'sparse') |
| - | 12.0±0.05ms | 6.54±0.02ms | 0.54 | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(3, 'dense') |
| - | 22.7±0.1ms | 8.99±0.04ms | 0.4 | polys.TimeSUBRESULTANTS_LinearDenseQuadraticGCD.time_op(3, 'sparse') |
| - | 5.26±0.05ms | 864±9μs | 0.16 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(1, 'sparse') |
| - | 12.8±0.08ms | 7.09±0.03ms | 0.56 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(2, 'sparse') |
| - | 102±0.7ms | 25.4±0.1ms | 0.25 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(3, 'dense') |
| - | 169±0.3ms | 53.3±0.2ms | 0.31 | polys.TimeSUBRESULTANTS_QuadraticNonMonicGCD.time_op(3, 'sparse') |
| - | 175±0.5μs | 112±0.9μs | 0.64 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(1, 'dense') |
| - | 359±1μs | 213±1μs | 0.59 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(1, 'sparse') |
| - | 4.31±0.01ms | 829±6μs | 0.19 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(3, 'dense') |
| - | 5.25±0.02ms | 381±0.8μs | 0.07 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(3, 'sparse') |
| - | 19.9±0.1ms | 2.81±0.02ms | 0.14 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(5, 'dense') |
| - | 22.7±0.2ms | 623±3μs | 0.03 | polys.TimeSUBRESULTANTS_SparseGCDHighDegree.time_op(5, 'sparse') |
| - | 474±3μs | 134±1μs | 0.28 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(1, 'sparse') |
| - | 4.75±0.02ms | 619±5μs | 0.13 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(3, 'dense') |
| - | 5.24±0.03ms | 140±2μs | 0.03 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(3, 'sparse') |
| - | 13.3±0.1ms | 1.29±0ms | 0.1 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(5, 'dense') |
| - | 14.0±0.1ms | 139±0.5μs | 0.01 | polys.TimeSUBRESULTANTS_SparseNonMonicQuadratic.time_op(5, 'sparse') |
| - | 132±0.5μs | 73.7±0.6μs | 0.56 | solve.TimeMatrixOperations.time_rref(3, 0) |
| - | 247±0.4μs | 87.2±0.5μs | 0.35 | solve.TimeMatrixOperations.time_rref(4, 0) |
| - | 24.4±0.1ms | 10.1±0.03ms | 0.42 | solve.TimeSolveLinSys189x49.time_solve_lin_sys |
| - | 28.5±0.3ms | 15.5±0.2ms | 0.54 | solve.TimeSparseSystem.time_linsolve_Aaug(20) |
| - | 54.6±0.5ms | 24.8±0.09ms | 0.45 | solve.TimeSparseSystem.time_linsolve_Aaug(30) |
| - | 28.1±0.2ms | 15.4±0.1ms | 0.55 | solve.TimeSparseSystem.time_linsolve_Ab(20) |
| - | 54.2±0.3ms | 24.6±0.1ms | 0.45 | solve.TimeSparseSystem.time_linsolve_Ab(30) |
Full benchmark results can be found as artifacts in GitHub Actions |
sympy/polys/tests/test_densetools.py
Outdated
assert dup_clear_denoms( | ||
[QQ(3), QQ(1), QQ(0)], QQ, ZZ) == (ZZ(1), [QQ(3), QQ(1), QQ(0)]) | ||
assert dup_clear_denoms( | ||
[QQ(1), QQ(1, 2), QQ(0)], QQ, ZZ) == (ZZ(2), [QQ(2), QQ(1), QQ(0)]) | ||
|
||
assert dup_clear_denoms([QQ(3), QQ( | ||
1), QQ(0)], QQ, ZZ, convert=True) == (ZZ(1), [ZZ(3), ZZ(1), ZZ(0)]) | ||
assert dup_clear_denoms([QQ(1), QQ( | ||
1, 2), QQ(0)], QQ, ZZ, convert=True) == (ZZ(2), [ZZ(2), ZZ(1), ZZ(0)]) | ||
assert dup_clear_denoms([QQ(3), QQ(1), QQ(0)], QQ, ZZ) == (ZZ(1), [QQ(3), QQ(1), QQ(0)]) | ||
assert dup_clear_denoms([QQ(1), QQ(1, 2), QQ(0)], QQ, ZZ) == (ZZ(2), [QQ(2), QQ(1), QQ(0)]) | ||
|
||
assert dup_clear_denoms( | ||
[EX(S(3)/2), EX(S(9)/4)], EX) == (EX(4), [EX(6), EX(9)]) | ||
assert dup_clear_denoms([QQ(3), QQ(1), QQ(0)], QQ, ZZ, convert=True) == (ZZ(1), [ZZ(3), ZZ(1), ZZ(0)]) | ||
assert dup_clear_denoms([QQ(1), QQ(1, 2), QQ(0)], QQ, ZZ, convert=True) == (ZZ(2), [ZZ(2), ZZ(1), ZZ(0)]) |
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.
Why have these tests been changed?
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.
sorry sir it seems like i haven't pushed the updated code because i have written the tests for RR.frac_field(x)
but i can't see it in this code....sorry for this
sympy/polys/tests/test_densetools.py
Outdated
|
||
assert dup_clear_denoms([EX(S(3)/2), EX(S(9)/4)], EX) == (EX(4), [EX(6), EX(9)]) |
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.
Does this example fail without the fix?
The problem in the issue was with the domain RR.frac_field(x)
.
sympy/polys/tests/test_densetools.py
Outdated
assert dup_clear_denoms([EX(7)], EX) == (EX(1), [EX(7)]) | ||
assert dup_clear_denoms([EX(sin(x)/x), EX(0)], EX) == (EX(x), [EX(sin(x)), EX(0)]) | ||
|
||
# This test is for inexact domain handling | ||
R, x = ring("x", RR) | ||
f = RR(0.5)*x + RR(0.333) | ||
common, cleared_f = dup_clear_denoms(f, RR) | ||
assert cleared_f == f, "Function should not modify input for inexact domains when no clear action is needed" |
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.
Look at the rest of the code in this file for examples of how to write the test code.
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.
Look at the rest of the code in this file for examples of how to write the test code.
sir i have used R.to_domain() with dup_decompose function but it does not seem to work
The operation to be tested is:
It is awkward to test output with floats but a string test is fine like `assert str(result) == "(x + ...". |
sir so do i have to add the test for specificaly this output? or it should be generalised for these type of polynomial expressions? |
sympy/polys/tests/test_densetools.py
Outdated
result_common_denom, result_transformed_elements = dup_clear_denoms([F(8.48717/(8.0089*x + 2.83)), F(0.0)], F) | ||
result_str = str((result_common_denom, result_transformed_elements)) | ||
expected_output_str = "(x + 0.353356890459364, [1.05971731448763, 0.0])" | ||
assert result_str == expected_output_str |
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 unnecessarily complicated:
result = dup_clear_denoms([F(8.48717/(8.0089*x + 2.83)), F(0.0)], F)
assert str(result) == "(x + 0.353356890459364, [1.05971731448763, 0.0])"
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.
sir i have updated it
Can you squash the commits? |
done sir |
The commits are not squashed. There are 12 commits but there should only be one. |
sir i am squashing the commits but it is still showing 12 on the commits tab |
…module, focusing on enhancing its efficiency and reliability when dealing with exact domains. The adjustments ensure that the function more accurately clears denominators, especially in scenarios involving symbolic expressions and rational numbers. Changes made include: - Fine-tuning the logic for handling denominators to ensure robust performance across a variety of use cases. - Streamlining the conversion process to guarantee that expressions are correctly converted to the target domain when requested. The primary aim of these modifications was to address feedback and improve the function's handling of symbolic and rational expressions, thereby increasing the utility and reliability of polynomial operations within Sympy. Updated tests reflect these changes by focusing on: - Verifying the accurate clearing of denominators in exact domains. - Ensuring the `convert` flag functions as intended across different scenarios. While initial considerations included enhancements for inexact domain handling, this version concentrates on exact domains to solidify the foundation of `dup_clear_denoms`. Future work may revisit inexact domain improvements. Fixes issue: sympy#26176 (sympy#26176) improved code quality Updated PR with comments Updated code quality Updated test cases for domain handling Updated code quality Added test with simplified expression Updated test Improved code quality Improved code quality improved code quality Updated PR with comments Updated code quality Updated test cases for domain handling Updated code quality Added test with simplified expression Updated test Improved code quality Improved code quality Squashed commits Updated PR with comments Updated code quality Updated test cases for domain handling Updated code quality Added test with simplified expression Updated test Improved code quality Improved code quality
edd8249
to
03df4d9
Compare
@@ -637,6 +635,9 @@ def test_dup_clear_denoms(): | |||
assert dup_clear_denoms([EX(7)], EX) == (EX(1), [EX(7)]) | |||
assert dup_clear_denoms([EX(sin(x)/x), EX(0)], EX) == (EX(x), [EX(sin(x)), EX(0)]) | |||
|
|||
F = RR.frac_field(x) | |||
result = dup_clear_denoms([F(8.48717/(8.0089*x + 2.83)), F(0.0)], F) | |||
assert str(result) == "(x + 0.353356890459364, [1.05971731448763, 0.0])" |
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'm not sure if it is generally a robust approach to use the str(result).
As far as I know, using exact value of float, can give fragile tests with
CPU vendors, math libraries, which may give slightly different numbers due to the implementation.
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 floats used here are mpmath floats which are based on only integer arithmetic and should be the same on all hardware. There isn't any good function currently for comparing polyelement approximately over RR.
References to other Issues or PRs
Fixes: #26176
Brief description of what is fixed or changed
Refined the
dup_clear_denoms
function within the polys module, focusing on enhancing its efficiency and reliability when dealing with exact domains. The adjustments ensure that the function more accurately clears denominators, especially in scenarios involving symbolic expressions and rational numbers.Other comments
Updated tests reflect these changes by focusing on:
Release Notes
dup_clear_denoms
function's efficiency in symbolic computations.