Skip to content

Draft: Refactor constraints to positive

James Kennington requested to merge feature-constraint-refactor into main

Change Summary

This MR refactors the way in which coordinate constraints are expressed logically. Previously, constraints were specified as functions that returned True when the given point was outside the interval of constraint (or failed to pass the constraint). This was counter intuitive in many cases. Presently, constraints are specified as functions that return True when the point is inside the interval of constraint (or passes the constraint).

Example:

Let m_1 be the coordiante we want to constrain in the interval [m_-, m_+] \subset \mathbb{R}. The below pseudo code shows the old and new ways of implementing this constraint:

def old_constraint(m1, bound_low, bound_high):
    # Returns True  if m1 invalid
    # Returns False if m1 valid 
    return m1 < bound_low or m1 > bound_high

def new_constraint(m1, bound_low, bound_high):
    # Returns False if m1 invalid
    # Returns True  if m1 valid 
    return m1 >= bound_low and m1 <= bound_high

Notes

More than Logical Inversion

This MR might seem to only logically invert the syntax of constraints in manifold; however, there is a key difference in edge case behavior. Previously, when a NaN was given, the constraint would return False (meaning Pass), since bool(numpy.nan) is False. This had the downstream effect of including erroneous templates in the bank (where coordinate functions failed). Now, when a NaN is given, the constraint returns False (meaning Fail).

Edited by James Kennington

Merge request reports