Skip to content

Enhancement/axis wise bounds NumberNode#471

Open
fastbodin wants to merge 25 commits intodwavesystems:mainfrom
fastbodin:enhancement/axis_wise_bounds_numbernode
Open

Enhancement/axis wise bounds NumberNode#471
fastbodin wants to merge 25 commits intodwavesystems:mainfrom
fastbodin:enhancement/axis_wise_bounds_numbernode

Conversation

@fastbodin
Copy link
Contributor

@fastbodin fastbodin commented Jan 30, 2026

Do not merge. Draft PR. Only C++ has been implemented. Simply checking CircleCi.

@fastbodin fastbodin force-pushed the enhancement/axis_wise_bounds_numbernode branch 2 times, most recently from bebd145 to 15f7b67 Compare February 3, 2026 23:11
@fastbodin
Copy link
Contributor Author

Feature is fully implemented.

@fastbodin fastbodin force-pushed the enhancement/axis_wise_bounds_numbernode branch from e3b0255 to 1c177b4 Compare February 4, 2026 00:02
@fastbodin fastbodin marked this pull request as ready for review February 4, 2026 20:24
@fastbodin
Copy link
Contributor Author

fastbodin commented Feb 4, 2026

Closes #216.

/// constraints on the sum of the values in each slice along `axis`.
/// Constraints can be defined for ALL slices along `axis` or PER slice along
/// `axis`. Allowable operators are defined by `BoundAxisOperator`.
struct BoundAxisInfo {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aesthetic, but I'd suggest calling this AxisBound and nesting BoundAxisOperator in it and calling that Operator. Also enum class. So NumberNode::AxisBound::Operator::Equal. A bit more succinct and IMO more clearly organized.

Copy link
Member

@arcondello arcondello Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also keep using an enum, so NumberNode::AxisBound::Equal but I usually prefer enum classes 🤷

Or keep the current.

Nah, changed my mind. enum class. See https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#renum-class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on all fronts. Much cleaner.

@arcondello arcondello requested a review from wbernoudy February 4, 2026 22:49
@arcondello arcondello added the enhancement New feature or request label Feb 4, 2026
@fastbodin
Copy link
Contributor Author

First round of comments addressed.

@fastbodin fastbodin force-pushed the enhancement/axis_wise_bounds_numbernode branch from 4b2205c to c6a93d5 Compare February 5, 2026 06:37
@wbernoudy
Copy link
Member

I do see "hyperslice" used in a lot of comments. Would prefer that is changed to just "slice" as well, or at least a small comment maybe in the header numbers.hpp on what that term means here.

Data is stored at C++ level with the class `AxisBoundInfo` as private
attribute to `NumberNode`. Added relevant C++ tests.
For each bound axis and each hyperslice along said axis, we store the
running sum of the values within the hyperslice. This state dependant
data is stored via `NumberNodeStateData`. If `NumberNode` is initialized
with values, we check that all axis-wise bounds are satisfied.
Added satisfies_axis_wise_bounds(), update_bound_axis_slice_sums(),
axis_wise_bounds(), and bound_axis_sums() to NumberNode. Updated various
NumberNode, IntegerNode, and BinaryNode methods to reference
NumberNodeStateData as opposed to ArrayNodeStateData. Updated all
NumberNode mutate methods to reflect changes to the axis-wise bound
running sums. Added C++ tests to check said mutate methods on
BinaryNode and IntegerNode.
Make use of BufferIterators to compute the sum of the values within each
hyperslice along each bound axis as opposed making a custom method to do
this.
Defined method to initialize_state() given exactly one axis-wise bound.
Fill state with lower bounds and increment until state satisfies
axis-wise bounds or determines infeasible. Added appropriate C++
IntegerNode and BinaryNode tests.
Made BoundAxisInfo and BoundAxisOperators members of NumberNode. Updated
all C++ tests. Optimized BufferIterator use in initialize_state().
Improved comments. Improved methods. Cleaned up C++ tests.
Added static_casts where necessary for CircleCI.
When constructing a state that satisfies exactly one axis-wise bound.
Needed for Cython interface. Changed relevant C++ code.
Used aliases in C++ NumberNode tests.
Also made BoundAxisOperaters an `enum` as opposed
to `enum class` because we found a Cython workaround.
@fastbodin fastbodin force-pushed the enhancement/axis_wise_bounds_numbernode branch from c6a93d5 to 72c6d96 Compare February 6, 2026 02:05
@fastbodin
Copy link
Contributor Author

Second round of comments addressed.

Copy link
Member

@arcondello arcondello left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Just two aesthetic comments

AxisBound(ssize_t axis, std::vector<Operator> axis_operators,
std::vector<double> axis_bounds);

/// The bound axis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems a bit inconsistent to have both public members and getter functions... I do see that the getters provide some functionality, so there might be instances where you'd like the choice. But I'm tempted to say you should make these private and force everyone to use the getter functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the honest answer is I made them public for ease of C++ testing. Agreed is inconsistent. Will change 👍.

if (bound_axis_sums[slice] < bound_axis_info.get_bound(slice)) return false;
break;
default:
unreachable();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do like putting an assert(false && "unexpected operator type") here for later debugging.

Made axis, operators, and bounds private members. Added axis(),
num_bounds(), and num_operators() methods. Updated C++ code/tests,
Python, and Cython to reflect this.
Removed `asserts()` that axis-wise bounds were satisfied
to `NumberNode::propagate()`.
@fastbodin
Copy link
Contributor Author

Third round of comments addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider adding the ability to specify one axis bound to BinaryVariable

3 participants