-
Notifications
You must be signed in to change notification settings - Fork 274
Speed up MatrixExpr.sum(axis=...) via quicksum
#1135
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
base: master
Are you sure you want to change the base?
Conversation
Adds a test to ensure that summing a matrix variable along an axis returns a MatrixExpr type instead of MatrixVariable, addressing issue scipopt#1117.
Enhanced the MatrixExpr.sum method to accept axis as int or tuple, handle keepdims, and provide better error checking for axis bounds. This improves compatibility with numpy's sum behavior and allows more flexible summation over matrix expressions.
Removed n=200 from the sum performance test to limit test size. Added additional performance assertions comparing np.ndarray.sum and the optimized sum method for matrix variables.
Renamed test_matrix_sum_argument to test_matrix_sum_axis and updated tests to use explicit axis arguments in sum operations. This clarifies the behavior when summing over all axes and improves test coverage for axis handling.
Replaces manual axis validation and normalization in MatrixExpr.sum with numpy's normalize_axis_tuple for improved reliability and code clarity. Updates type hints and simplifies logic for summing across all axes.
Added tests to verify error handling in matrix variable sum operations for invalid axis types, out-of-range values, and duplicate axes.
Introduces test cases to verify the shape of matrix variable sums when using the keepdims argument, ensuring correct behavior for both full and axis-specific summation.
Replaces the use of the 'axis' keyword argument with a positional argument in the z.sum() method call to align with the expected function signature.
Replaces np.fromiter with np.apply_along_axis for summing along specified axes in MatrixExpr. This simplifies the code and improves readability.
Added a comment to clarify the purpose of the test_matrix_sum_axis function, indicating it compares the result of summing a matrix variable after optimization.
The docstring for the MatrixExpr.sum method was updated to provide detailed information about parameters, return values, and behavior, improving clarity and alignment with numpy conventions.
Updated the docstring for MatrixExpr.sum to specify that it uses quicksum for speed optimization instead of numpy.ndarray.sum. Added a detailed note explaining the difference between quicksum (using __iadd__) and numpy's sum (using __add__).
Renamed the existing performance test to clarify it tests the case where axis is None. Added a new test to measure performance when summing along a specific axis.
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.
Pull request overview
This pull request speeds up MatrixExpr.sum(axis=...) operations by using quicksum instead of the default numpy.ndarray.sum. The optimization addresses issues #1133 and #1070, extending the previous optimization for axis=None to support partial axis summation. The implementation also adds comprehensive test coverage for error handling, correctness verification, and performance benchmarking.
Key Changes
- Refactored
MatrixExpr.sum()to usequicksumfor all axis configurations, including partial axis sums vianp.apply_along_axis - Added detailed docstring following NumPy documentation style with parameter descriptions and return type specifications
- Expanded test suite with error validation tests, correctness tests using parametrization, and performance benchmarks for both
axis=Noneandaxis!=Nonecases
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/pyscipopt/matrix.pxi | Reimplemented sum() method with quicksum optimization, axis normalization, and comprehensive documentation; added imports for typing and numpy utilities |
| tests/test_matrix_variable.py | Added CONST import, split tests into test_matrix_sum_error, test_matrix_sum_axis, test_matrix_sum_result, added new performance test test_matrix_sum_axis_not_none_performance, and added test_matrix_sum_return_type |
| CHANGELOG.md | Documented the performance improvement and type fix in the Unreleased section |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| np_res = a.sum(axis, keepdims=keepdims) | ||
| scip_res = MatrixExpr.sum(a, axis, keepdims=keepdims) |
Copilot
AI
Dec 18, 2025
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 test attempts to call MatrixExpr.sum(a, axis, keepdims=keepdims) where a is a plain numpy array of integers (np.arange(6).reshape((1, 2, 3))), not a MatrixExpr containing Expr objects. The test then tries to access e.terms[CONST] on each element, but integers don't have a terms attribute. This test will fail with an AttributeError. Consider creating a proper MatrixExpr with Expr objects or using a MatrixVariable instead.
| np_res = a.sum(axis, keepdims=keepdims) | |
| scip_res = MatrixExpr.sum(a, axis, keepdims=keepdims) | |
| # build an array of Expr objects matching the numeric values in `a` | |
| a_expr = np.vectorize(Expr)(a) | |
| np_res = a.sum(axis, keepdims=keepdims) | |
| scip_res = MatrixExpr.sum(a_expr, axis, keepdims=keepdims) |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…nto issue/1133
Refactored the sum method in MatrixExpr to clarify axis typing and simplify the application of np.apply_along_axis. The new implementation improves readability and maintains the intended behavior.
|
Hey @Zeroto521 is this ready for review? |
yes |
close to #1133 and #1070