Skip to content

Enable Coefficients for DiscreteSumConstraint and from_simplex#786

Open
Scienfitz wants to merge 10 commits into
mainfrom
feature/sum_constraint_coefficients
Open

Enable Coefficients for DiscreteSumConstraint and from_simplex#786
Scienfitz wants to merge 10 commits into
mainfrom
feature/sum_constraint_coefficients

Conversation

@Scienfitz
Copy link
Copy Markdown
Collaborator

@Scienfitz Scienfitz commented Apr 29, 2026

use-case motivated addition:

  • DiscreteSumConstraint gets a coefficients that works akin to whats been done in the continuous constraint
  • from_simplex gets a simplex_coefficients keyword that allows specifying coefficients for the simplex parameters. This is possible by changing the way the max/min incoming sums are assessed
  • I'm using matrix multiplication @ for from_simplex because we ensure by construciton that the incoming array is contiguous and does not have to be copied for a reshape and multiplication. This contiguousness is not guaranteed for data[params] in get_invalid in DiscreteSumConstraint so its more memory efficient to use per-column approaches in the assumption of a small countable amount of parameters (usually the case)

Unrelated optimization
I also replaced the inner loop of from_simplex to use numpy and not pandas. This is also motivated by memory and time efficiency. This commit can be dropped tho if undesired, but there are singificant time and mem savings:

Scenario Rows main time (s) feature time (s) Δ time main mem (MB) feature mem (MB) Δ mem
4p × 11v 1,001 0.013 0.002 -88% 0.4 0.2 -49%
6p × 11v 8,008 0.039 0.002 -94% 4.3 3.2 -26%
8p × 11v 43,758 0.193 0.011 -94% 35.1 27.9 -20%
6p × 21v 230,230 0.672 0.032 -95% 141.1 106.1 -25%
6p × 21v boundary 53,130 0.736 0.032 -96% 141.1 106.1 -25%

(p = simplex parameters, v = values)

@Scienfitz Scienfitz self-assigned this Apr 29, 2026
@Scienfitz Scienfitz added enhancement Expand / change existing functionality new feature New functionality labels Apr 29, 2026
Scienfitz added 8 commits May 7, 2026 12:38
Follows the ContinuousLinearConstraint pattern: coefficients default to
all-ones (preserving existing behavior), are validated for length parity
with parameters, and the weighted sum is evaluated via a single numpy
matrix-vector product to avoid intermediate DataFrame copies.
Reworks the signature to make all optional arguments keyword-only (via *).
Adds simplex_coefficients for a weighted simplex sum constraint. The
incremental early-pruning algorithm is generalised to handle negative
coefficients correctly by computing per-parameter weighted min/max
contributions rather than assuming monotonicity, and by keeping nonzero
cardinality tracking separate (raw parameter values, coefficient-sign
independent). The weighted row-sum uses a single numpy matrix-vector
product to avoid intermediate DataFrame copies.
…plex_coefficients

Weighted-sum filtering correctness (default and custom coefficients) added
to the existing discrete constraint test file, parametrized across all-ones,
scaled, negative, and equality operator cases. Simplex coefficient tests
(brute-force equivalence, mixed-sign, boundary_only, and equivalence with
from_product+DiscreteSumConstraint) added to the existing from_simplex test
file. Validation error tests for length mismatch added to the constraint
validation test file.
… sum

The previous approach (to_numpy() @ np.asarray(coefficients)) consolidates
all referenced columns into a contiguous (N, k) array before computing the
dot product. When the constraint parameters are non-adjacent columns in the
DataFrame this forces a full (N, k) memory copy regardless.

For the typical use case of sum constraints (k < 10 parameters), a
column-by-column accumulation avoids this: each data[p].to_numpy() is a
zero-copy view of a single contiguous column, the scalar multiply produces
one (N,) temporary, and the built-in sum accumulates in-place. No (N, k)
consolidation allocation is needed.

Also removes the now-unused numpy import.
Replaces the pandas-based inner loop (pd.merge cross-join, pd.DataFrame,
df.drop inplace) with raw numpy operations (np.repeat + np.tile +
np.column_stack for cross-joins, boolean indexing for pruning). The
DataFrame is created once at the end. This avoids per-iteration pandas
overhead (index management, BlockManager, merge machinery) and reduces
peak memory by eliminating duplicate DataFrame+numpy representations.
@Scienfitz Scienfitz force-pushed the feature/sum_constraint_coefficients branch from f8b3f17 to cce898a Compare May 7, 2026 11:20
@Scienfitz Scienfitz marked this pull request as ready for review May 7, 2026 11:48
Copilot AI review requested due to automatic review settings May 7, 2026 11:48
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 PR extends BayBE’s discrete constraint and search space construction capabilities by adding weighted-sum support to DiscreteSumConstraint and enabling weighted simplex construction via SubspaceDiscrete.from_simplex(simplex_coefficients=...). It also refactors the hot loop in from_simplex to use NumPy arrays for improved performance and memory usage.

Changes:

  • Add coefficients to DiscreteSumConstraint (defaulting to all ones) and apply weighting in both pandas and polars evaluation paths.
  • Add keyword-only simplex_coefficients to SubspaceDiscrete.from_simplex (defaulting to all ones) and adjust pruning logic to work with weighted sums.
  • Expand test coverage for the new weighted behaviors and length-mismatch validation.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
baybe/constraints/discrete.py Adds DiscreteSumConstraint.coefficients with validation + weighted evaluation (pandas/polars).
baybe/searchspace/discrete.py Adds simplex_coefficients, makes args keyword-only, and rewrites from_simplex construction loop using NumPy with weighted pruning.
CHANGELOG.md Documents the new weighted features and the keyword-only breaking change for from_simplex.
tests/validation/test_constraint_validation.py Adds validation test for DiscreteSumConstraint coefficients length mismatch.
tests/hypothesis_strategies/constraints.py Updates Hypothesis discrete-constraint strategy generation to optionally include coefficients.
tests/hypothesis_strategies/alternative_creation/test_searchspace.py Adds brute-force parity tests for weighted simplex generation and mismatch validation.
tests/constraints/test_constraints_polars.py Adds parity test to ensure polars vs pandas agree for weighted sum constraints.
tests/constraints/test_constraints_discrete.py Adds behavioral tests for weighted sum constraints in the discrete constraint suite.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread baybe/searchspace/discrete.py
Comment thread baybe/searchspace/discrete.py Outdated
Scienfitz and others added 2 commits May 7, 2026 14:22
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@Scienfitz Scienfitz force-pushed the feature/sum_constraint_coefficients branch from 466cf21 to a232085 Compare May 7, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Expand / change existing functionality new feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants