-
Notifications
You must be signed in to change notification settings - Fork 269
BUG: _VarArray
can't handle MatrixVar
#1044
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
Simplifies and clarifies the logic for initializing _VarArray by restructuring type checks and error handling. Now uses f-strings for error messages and ensures consistent handling of empty lists and invalid types.
Updated the _VarArray class constructor to handle MatrixVariable inputs in addition to Variable, list, and tuple. Refactored pointer allocation logic into a helper function for improved code clarity and maintainability.
Introduces a new test to verify that addConsIndicator works correctly when the binary variable is a matrix variable, addressing issue scipopt#1043.
To fix "Storing unsafe C derivative of temporary Python reference"
The create_ptr function in _VarArray.__cinit__ no longer takes a separate size argument and instead uses len(vars) directly. This simplifies the function signature and reduces redundancy.
Inlined the pointer creation logic in _VarArray's __cinit__ method, removing the inner create_ptr function. This simplifies the code and improves readability while maintaining the same functionality.
The test now checks addConsIndicator with both activeone=True and activeone=False, and updates the objective to use binvar.sum().
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1044 +/- ##
==========================================
+ Coverage 54.13% 54.32% +0.19%
==========================================
Files 22 23 +1
Lines 5045 5257 +212
==========================================
+ Hits 2731 2856 +125
- Misses 2314 2401 +87 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Sorry, what's the status of this? |
Waiting for your opinion on #1044 (comment) whether a matrix is a list and an explanation on which feature this aims at. Currently, I do not see a method which intends to apply |
src/pyscipopt/scip.pxi
Outdated
self.size = len(vars) | ||
self.ptr = <SCIP_VAR**> malloc(self.size * sizeof(SCIP_VAR*)) if self.size else NULL | ||
for i, var in enumerate(vars): | ||
if not isinstance(var, Variable): | ||
raise TypeError(f"Expected Variable, got {type(var)}.") | ||
self.ptr[i] = (<Variable>var).scip_var |
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.
self.size = len(vars) | |
self.ptr = <SCIP_VAR**> malloc(self.size * sizeof(SCIP_VAR*)) if self.size else NULL | |
for i, var in enumerate(vars): | |
if not isinstance(var, Variable): | |
raise TypeError(f"Expected Variable, got {type(var)}.") | |
self.ptr[i] = (<Variable>var).scip_var | |
if vars: | |
self.size = len(vars) | |
self.ptr = <SCIP_VAR**> malloc(self.size * sizeof(SCIP_VAR*)) | |
for i, var in enumerate(vars): | |
if not isinstance(var, Variable): | |
raise TypeError(f"Expected Variable, got {type(var)}.") | |
self.ptr[i] = (<Variable>var).scip_var |
Together with https://github.com/scipopt/PySCIPOpt/pull/1044/files#r2281629510.
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 forgot that this line has a problem. @DominikKamp
numpy.ndarray
will raise an error if the size is larger than 2.
if vars:
In my local model, it raised an error with the head of the commit building package.
from pyscipopt import Model
model = Model()
vars = model.addMatrixVar(3, vtype="B")
model.addConsKnapsack(vars, [1, 2, 3], 5)
model.setObjective(vars.sum(), "maximize")
model.optimize()
# Traceback (most recent call last):
# line 5, in <module>
# model.addConsKnapsack(vars, [1, 2, 3], 5)
# File "src/pyscipopt/scip.pxi", line 6463, in pyscipopt. scip.Model.addConsKnapsack
# File "src/pyscipopt/scip.pxi", line 2512, in pyscipopt.scip._VarArray.__cinit__
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
It should be kept original, in my mind. Since self.size
and self.ptr
are both initiated at the top.
self.size = len(vars)
self.ptr = <SCIP_VAR**> malloc(self.size * sizeof(SCIP_VAR*)) if self.size else NULL
for i, var in enumerate(vars):
if not isinstance(var, Variable):
raise TypeError(f"Expected Variable, got {type(var)}.")
self.ptr[i] = (<Variable>var).scip_var
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.
So a matrix variable is an ndarray and not a list. I would suggest pulling the initialization of self.size
by len(vars)
down here and update the condition to self.size
. We do not need to enumerate an empty something.
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.
Otherwise, this is fine.
Ensures _VarArray initializes ptr and size to NULL and 0, respectively, before processing input. Prevents allocation and assignment errors when an empty or invalid input is provided.
Co-authored-by: DominikKamp <130753997+DominikKamp@users.noreply.github.com>
@DominikKamp anything else or can I merge? |
Merge as to be continued with logged change. |
Thank you @Zeroto521 ! |
fix #1043