Skip to content

WIP: Functional constraints #18

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

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
115 commits
Select commit Hold shift + click to select a range
b7800c5
adding custom basis for quick testing
Jimmy-INL Feb 10, 2022
62b79a2
retrieving previous version
Jimmy-INL Feb 10, 2022
ceb456a
adding the custom basis
Jimmy-INL Feb 10, 2022
1ccd23f
adding the tutorial
Jimmy-INL Feb 17, 2022
20c2460
readding custom basis
Jimmy-INL May 12, 2022
1cbcc13
resolving conflicts
Jimmy-INL May 12, 2022
960d971
trying to have the basis matrix as the identity matrix
Jimmy-INL May 15, 2022
db3c6cb
Adding region constraint notebook
Jun 24, 2022
dbbb980
Tried to fix the const_sensors = 0 error
Jun 24, 2022
4fb1085
Fixing n_const_sensssors = 0, and edding checks for limitations
Jimmy-INL Jun 25, 2022
c011daf
pushing the notebook to compare changes
Jimmy-INL Jun 25, 2022
fb5ea4e
starting the conversion from notebook to script, and fixing the zero …
Jimmy-INL Jun 27, 2022
0e5f9ca
Resolving conflicts
Jun 27, 2022
daee413
Adding Script for gqr
Jun 27, 2022
bb9a251
Script updated with Linear indices function for Twist prototype
Jun 29, 2022
f71f77d
Adding gqr with new function for optimal constraint sensor placement …
Jul 6, 2022
9cb0a4a
minor changes to the examples/region_optimal.ipynb and _gqr
Jimmy-INL Jul 11, 2022
2fdf2f0
Merge branch 'master' of https://github.com/Jimmy-INL/pysensors into …
Jul 11, 2022
59e05ab
Merge branch 'niharika-krithika-mohammad-regionConstraints' of https:…
Jul 11, 2022
0a3477d
Adding different cases in f_region
Jul 12, 2022
7d75143
Merge branch 'custom-Basis' into niharika-krithika-mohammad-regionCon…
Jul 12, 2022
16b8427
Merge branch 'Jimmy-adding-customBasis' into niharika-krithika-mohamm…
Jimmy-INL Jul 13, 2022
876d6fb
Adding the Trace(R) calculation
Jul 13, 2022
ea74f8f
Adding updated gqr with constraints moved to utils and region_optimal…
Jul 28, 2022
772b525
Small corrections in _constraints
Jul 28, 2022
434903b
Merge branch 'niharika-krithika-mohammad-regionConstraints' of https:…
Jimmy-INL Aug 2, 2022
c0ab251
Separating constraint processing function from the function for dlens…
Aug 2, 2022
3484e08
Adding options to call different type of constraints and renaming fun…
Aug 4, 2022
db7d378
Merge branch 'niharika-krithika-mohammad-regionConstraints' of https:…
Jimmy-INL Aug 5, 2022
b8b3717
Few changes to gqr and region_optimal which has the radius constraints
Aug 8, 2022
8788790
Fixing dlens issues
Aug 8, 2022
885add4
Adding _validation in utils with determinant and relative reconstruct…
Aug 8, 2022
69a5511
Adding predtermined_norm_calc to gqr
Aug 10, 2022
ab4bdbd
Moving norm_calculation functions to utilities
Aug 15, 2022
67d3bb8
Adding all updates
Aug 25, 2022
f434583
Merge branch 'niharika-krithika-mohammad-regionConstraints' of https:…
Sep 23, 2022
5671ebb
Modifying radii_constraints code and gqr now works as a script for ra…
Oct 13, 2022
55a1005
Merge branch 'niharika-krithika-mohammad-regionConstraints' of https:…
Jimmy-INL Oct 18, 2022
284a752
stating to clear _gqr
Jimmy-INL Oct 27, 2022
e011bf8
undo old changes to _identity.py
Jimmy-INL Oct 27, 2022
9f1d5e6
more cleaning, first two constraints fixed
Jimmy-INL Nov 1, 2022
720290f
more cleaning
Jimmy-INL Nov 19, 2022
80b68b4
fixing tests
Jimmy-INL Nov 19, 2022
3408c9b
removing notebooks and unnecessary mods
Jimmy-INL Nov 19, 2022
3254b89
Delete basis_comparison-Copy1.ipynb
Jimmy-INL Nov 19, 2022
acf2f36
Delete cost_constrained_qr.ipynb
Jimmy-INL Nov 19, 2022
1f6ec68
Delete region_optimal.ipynb
Jimmy-INL Nov 19, 2022
9346b79
Delete region_qrModified.ipynb
Jimmy-INL Nov 19, 2022
b412708
Delete region_qrModified.py
Jimmy-INL Nov 19, 2022
616ecf1
removing notebooks and unnecessary mods
Jimmy-INL Nov 19, 2022
9c01b1b
Merge branch 'cleaningGQR' of https://github.com/Jimmy-INL/pysensors …
Jimmy-INL Nov 19, 2022
0313052
removing notebooks and unnecessary mods
Jimmy-INL Nov 19, 2022
023dcb2
removing notebooks and unnecessary mods
Jimmy-INL Nov 19, 2022
c5b1903
removing notebooks and unnecessary mods
Jimmy-INL Nov 19, 2022
b66409e
removing notebooks and unnecessary mods
Jimmy-INL Nov 19, 2022
8d054d2
Merge https://github.com/Jimmy-INL/pysensors into TestingPR
Nov 29, 2022
694ff9e
Merge branch 'cleaningGQR' of https://github.com/Jimmy-INL/pysensors …
Nov 29, 2022
7fb6978
Revised PR
Dec 1, 2022
43ee27d
Revised PR by Niharika
Dec 1, 2022
1c16f67
Removed a validation
Jimmy-INL Dec 2, 2022
0a1787f
removing validation from __init__
Jimmy-INL Dec 4, 2022
f558ff5
fixing and adding validation
Jimmy-INL Dec 14, 2022
ce2b463
allowing user-defined constraints
Jimmy-INL Dec 28, 2022
c96713c
cleaning
Jimmy-INL Dec 29, 2022
dc1c099
adding the user-defined constraints
Jimmy-INL Dec 29, 2022
39964d7
Adding updates to constraints
Jan 19, 2023
fc928d7
Constraint for TWIST
Jan 20, 2023
a1000cb
Adding updated optimizer gqr
Feb 21, 2023
6cf420c
Adding radii constraints
Mar 9, 2023
41bc87f
Adding radii constraints
Mar 9, 2023
07adfbd
Adding radii constraints
Mar 9, 2023
0ed0c5b
Fixing bug caused when I added radii constraints in _gqr'
Mar 28, 2023
7df15af
trying to fix the max and excat multiple user defined constraints
Jimmy-INL Apr 27, 2023
69f1123
removing a for loop
Jimmy-INL Jun 23, 2023
b5d1623
Adding documentation for functions in _constraints and updating __ini…
Jul 6, 2023
8839571
Adding classes for functional constraints in _constraints.py
niharika2999 Jul 7, 2023
8e9bbc8
Adding BaseConstraint, circle, Line class to _constraints
niharika2999 Jul 10, 2023
471c42d
Adding notebook to test functional_constraints.ipynb functional const…
niharika2999 Jul 10, 2023
a5e447e
Removing functional constraints helper functions from BaseConstraints
niharika2999 Jul 10, 2023
df2bcd1
Moving constraint definitions to circle, line etc. class and adding n…
niharika2999 Jul 11, 2023
327fd91
adding a userDefinedConstraints class to handle various functions def…
niharika2999 Jul 11, 2023
aa37422
Moving constraint evaluation and plotting (just constraint and constr…
niharika2999 Jul 12, 2023
5a099a1
Adding user defined plotting functionalities and updating the jupyter…
niharika2999 Jul 12, 2023
895a824
Merge branch 'Ni_converting_functional-constraints_class' into functi…
joshua-cogliati-inl Jul 13, 2023
154e9ef
Adding, plot_grid, sensors_dataframe, annotate_sensors functionalitie…
niharika2999 Jul 17, 2023
8487c8d
Adding X_axis, Y_axis Fields, etc declarations to the __init__() and …
niharika2999 Jul 18, 2023
7a395c2
Adding updates to constraints
niharika2999 Aug 4, 2023
57b55a0
Backing up all code from INL laptop onto github
niharika2999 Aug 24, 2023
fc0ef9c
Merge remote-tracking branch 'niharika2999/Ni_converting_functional-c…
joshua-cogliati-inl Sep 15, 2023
c356721
Switching to Ni_converting_functional-constraints_class
joshua-cogliati-inl Sep 15, 2023
c95d313
Deleting file not in main version.
joshua-cogliati-inl Sep 15, 2023
91c7e69
Adding parabola constraints, updating notebooks and rearrnginf functi…
Sep 28, 2023
38bc452
Adding parabola constraints python file
Sep 28, 2023
1203fe9
Adding functionality of user giving just an equation as an input to u…
Oct 16, 2023
974034f
Adding documentation for all of the functions in _constraints.py
Oct 16, 2023
81c4a93
Fixing exact_n for number of sensors required in the constrained regi…
Oct 17, 2023
f84cccb
Adding all of the chnages suggested by Mohammad in his PR titled ( fe…
Oct 20, 2023
c4d31d6
Fixing annotate_sensors() to work for dataframe data and unifying the…
Oct 24, 2023
d54a063
Adding capability of plotting multiple things on the same axis as wel…
Oct 27, 2023
bec5b27
Fixing ellipse without an angle (the issue was with the plotting func…
Oct 27, 2023
f655d99
Adding functions for an ellipse rotated by an angle in constraint_fun…
Oct 27, 2023
8346c5f
Pushing any changes on my branch so as to test Mohammad's changes
Oct 30, 2023
05ae712
Commiting before switching branch to fix distance constraints
Dec 5, 2023
2cf319f
revising user-defined constraints and fixing tests
Jimmy-INL Dec 25, 2023
9609b11
adding a cylinder class for thew fuel problem
Jimmy-INL Dec 30, 2023
79f40b1
making all gs of type bool
Jimmy-INL Dec 30, 2023
475d795
making all gs of type bool
Jimmy-INL Dec 30, 2023
c8364d1
returning 3d tuples for coords except for cylinders
Jimmy-INL Dec 30, 2023
5c192c7
adding cylinder to __init__
Jimmy-INL Jan 4, 2024
d7ab38e
repushing mods to _constraints. Possible breakage
Jimmy-INL Jan 8, 2024
36c5576
enhancing constrai nt plotting
Jimmy-INL Jan 11, 2024
54b5346
undowing an exception that was replaced by mistake
Jimmy-INL Jan 11, 2024
95258ce
standerdize inFlag in all constraints
Jimmy-INL Jan 11, 2024
33b37d7
fixing alpha of constraints
Jimmy-INL Jan 18, 2024
a7e8073
Merge remote-tracking branch 'niharika2999/Ni_converting_functional-c…
joshua-cogliati-inl Feb 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,813 changes: 1,813 additions & 0 deletions examples/OPTITWIST_functional_constraints.ipynb

Large diffs are not rendered by default.

370 changes: 0 additions & 370 deletions examples/cost_constrained_qr.ipynb

This file was deleted.

44 changes: 44 additions & 0 deletions examples/twistParabolicConstraint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

import numpy as np

def twistParabolicConstraint(x,y,**kwargs):
"""
Function for evaluating constrained sensor locations on the grid by returning a negative value (if index is constrained) and a positive value (if index is unconstrained).

Parameters
----------
x: float, x coordinate of all grid-points considered for sensor placement
y : float, y coordinate of all grid-points considered for sensor placement

**kwargs : h : float, x-coordinate of the vertex of the parabola we want to be constrained;
k : float, y-coordinate of the vertex of the parabola we want to be constrained;
a : float, The x-coordinate of the focus of the parabola.

Returns
-------
g : np.darray, shape [No. of grid points],
A boolean array for every single grid point based on whether the grid point lies in the constrained region or not
"""
# make sure the length of x is the same as y
assert len(x) == len(y)
if ('h' not in kwargs.keys()) or (kwargs['h'] == None) :
kwargs['h'] = 0.025
if ('k' not in kwargs.keys()) or (kwargs['k'] == None) :
kwargs['k'] = 0
if ('a' not in kwargs.keys()) or (kwargs['a'] == None) :
kwargs['a'] = 100
# initialize the constraint evaluation function g
g1 = np.zeros(len(x),dtype=float) - 1
g2 = np.zeros(len(x),dtype=float) - 1
g = np.zeros(len(x),dtype=float)
# loop over all given location and check if they violate the constraints
# make sure the retuned value is negative if it is in the constrained area and positive otherwise
for i in range(len(x)):
# circle of center (h,k)=(0,0) and radius 2.5 cm
g1[i] = (kwargs['a']*(x[i]-kwargs['h'])**2) - (y[i]-kwargs['k'])
#
# Second constraint:
g2[i] = y[i] - 0.2
if bool(g1[i]>=0) == bool(g2[i]>=0):
g[i] = (bool(g1[i]>=0) and bool(g2[i]>=0))-1
return g
10 changes: 10 additions & 0 deletions examples/userExplicitConstraint1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import numpy as np

def userExplicitConstraint1(x,y,**kwargs):
'''
'''
assert len(x) == len(y)
g = np.zeros(len(x),dtype=float)
for i in range(len(x)):
g[i] = ((x[i]-30)**2 + (y[i]-40)**2) - 5**2
return g
4 changes: 4 additions & 0 deletions examples/userExplicitConstraint2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

def userExplicitConstraint2(x,y,**kwargs):
g = (x-20)**2 + (y-10)**2 - 49
return g
4 changes: 2 additions & 2 deletions pysensors/basis/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ._identity import Identity
from ._random_projection import RandomProjection
from ._svd import SVD
from ._custom import Custom


__all__ = ["Identity", "SVD", "RandomProjection"]
__all__ = ["Identity", "SVD", "RandomProjection","Custom"]
88 changes: 88 additions & 0 deletions pysensors/basis/_custom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""
custom mode basis class.
"""
from ._base import InvertibleBasis
from ._base import MatrixMixin

class Custom(InvertibleBasis, MatrixMixin):
"""
Use a custom transformation to map input features to
custom modes.

Assumes the data has already been centered (to have mean 0).

Parameters
----------
n_basis_modes : int, optional (default 10)
Number of basis modes to retain. Cannot be larger than
the number of features ``n_features``, or the number of examples
``n_examples``.
U: The custom basis matrix

Attributes
----------
basis_matrix_ : numpy ndarray, shape (n_features, n_basis_modes)
The top n_basis_modes left singular vectors of the training data.

"""

def __init__(self, U, n_basis_modes=10, **kwargs):
if isinstance(n_basis_modes, int) and n_basis_modes > 0:
super(Custom, self).__init__()#n_components=n_basis_modes, **kwargs
self._n_basis_modes = n_basis_modes
self.custom_basis_ = U
else:
raise ValueError("n_basis_modes must be a positive integer.")

def fit(self, X):
"""
Parameters
----------
X : array-like, shape (n_samples, n_features)
The training data.

Returns
-------
self : instance
"""
# self.basis_matrix_ = self.custom_basis_[:,: self.n_basis_modes] @ self.custom_basis_[:,: self.n_basis_modes].T @ X[: self.n_basis_modes, :].T.copy()
# self.basis_matrix_ = self.custom_basis_ @ self.custom_basis_.T @ X[: self.n_basis_modes, :].T.copy()
self.basis_matrix_ = self.custom_basis_[:,:self.n_basis_modes]
# self.basis_matrix_ = (X @ self.custom_basis_[:,:self.n_basis_modes] @ self.custom_basis_[:,:self.n_basis_modes].T)[:self.n_basis_modes,:].T

# self.basis_matrix_ = ((X @ self.custom_basis_).T)[:,:self.n_basis_modes]
# self.basis_matrix_ = ((X @ self.custom_basis_ @ self.custom_basis_.T).T)[:,:self.n_basis_modes]
return self

def matrix_inverse(self, n_basis_modes=None):
"""
Get the inverse matrix mapping from measurement space to
coordinates with respect to the basis.

Note that this is not the inverse of the matrix returned by
``self.matrix_representation``. It is the (pseudo) inverse of
the matrix whose columns are the basis modes.

Parameters
----------
n_basis_modes : positive int, optional (default None)
Number of basis modes to be used to compute inverse.

Returns
-------
B : numpy ndarray, shape (n_basis_modes, n_features)
The inverse matrix.
"""
n_basis_modes = self._validate_input(n_basis_modes)

return self.basis_matrix_[:, :n_basis_modes].T

@property
def n_basis_modes(self):
"""Number of basis modes."""
return self._n_basis_modes

@n_basis_modes.setter
def n_basis_modes(self, n_basis_modes):
self._n_basis_modes = n_basis_modes
self.n_components = n_basis_modes
2 changes: 1 addition & 1 deletion pysensors/classification/_sspoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ def fit(

if self.threshold is None:
# Chosen as in Brunton et al. (2016)
threshold = np.sqrt(np.sum(s**2)) / (
threshold = np.sqrt(np.sum(s ** 2)) / (
2 * self.basis_matrix_inverse_.shape[0] * n_classes
)
else:
Expand Down
3 changes: 2 additions & 1 deletion pysensors/optimizers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from ._ccqr import CCQR
from ._qr import QR

from ._gqr import GQR

__all__ = [
"CCQR",
"QR",
"GQR"
]
125 changes: 125 additions & 0 deletions pysensors/optimizers/_gqr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import numpy as np
import pysensors

from pysensors.optimizers._qr import QR

import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn import metrics
from mpl_toolkits.axes_grid1 import make_axes_locatable

import pysensors as ps
from matplotlib.patches import Circle
from pysensors.utils._norm_calc import returnInstance as normCalcReturnInstance

class GQR(QR):
"""
General QR optimizer for sensor selection.
Ranks sensors in descending order of "importance" based on
reconstruction accuracy. This is an extension that requires a more intrusive
access to the QR optimizer to facilitate a more adaptive optimization. This is a generalized version of cost constraints
in the sense that users can allow `n_const_sensors` in the constrained area.
if n = 0 this converges to the CCQR results. and if no constrained region it should converge to the results from QR optimizer.

See the following reference for more information
Manohar, Krithika, et al.
"Data-driven sparse sensor placement for reconstruction:
Demonstrating the benefits of exploiting known patterns."
IEEE Control Systems Magazine 38.3 (2018): 63-86.

@ authors: Niharika Karnik (@nkarnik2999), Mohammad Abdo (@Jimmy-INL), and Krithika Manohar (@kmanohar)
"""
def __init__(self):
"""
Attributes
----------
pivots_ : np.ndarray, shape [n_features]
Ranked list of sensor locations.
idx_constrained : np.ndarray, shape [No. of constrained locations]
Column Indices of the sensors in the constrained locations.
n_sensors : integer,
Total number of sensors
n_const_sensors : integer,
Total number of sensors required by the user in the constrained region.
all_sensors : np.ndarray, shape [n_features]
Optimally placed list of sensors obtained from QR pivoting algorithm.
constraint_option : string,
max_n_const_sensors : The number of sensors in the constrained region should be less than or equal to n_const_sensors.
exact_n_const_sensors : The number of sensors in the constrained region should be exactly equal to n_const_sensors.
"""
self.pivots_ = None
self.idx_constrained = []
self.n_sensors = None
self.n_const_sensors = 0
self.all_sensors = []
self.constraint_option = ''
self.nx = None
self.ny = None
self.r = 1

def fit(self,basis_matrix,**optimizer_kws):
"""
Parameters
----------
basis_matrix: np.ndarray, shape [n_features, n_samples]
Matrix whose columns are the basis vectors in which to
represent the measurement data.
optimizer_kws: dictionary, optional
Keyword arguments to be passed to the qr method.

Returns
-------
self: a fitted :class:`pysensors.optimizers.GQR` instance
"""
[setattr(self,name,optimizer_kws.get(name,getattr(self,name))) for name in optimizer_kws.keys()]
self._norm_calc_Instance = normCalcReturnInstance(self, self.constraint_option)
n_features, n_samples = basis_matrix.shape # We transpose basis_matrix below
max_const_sensors = len(self.idx_constrained) # Maximum number of sensors allowed in the constrained region

## Assertions and checks:
# if self.n_sensors > n_features - max_const_sensors + self.nConstrainedSensors:
# raise IOError ("n_sensors cannot be larger than n_features - all possible locations in the constrained area + allowed constrained sensors")
# if self.n_sensors > n_samples + self.nConstrainedSensors: ## Handling zero constraint?
# raise IOError ("Currently n_sensors should be less than min(number of samples, number of modes) + number of constrained sensors,\
# got: n_sensors = {}, n_samples + const_sensors = {} + {} = {}".format(self.n_sensors,n_samples,self.nConstrainedSensors,n_samples+self.nConstrainedSensors))

# Initialize helper variables
R = basis_matrix.conj().T.copy()
p = np.arange(n_features)
k = min(n_samples, n_features)


for j in range(k):
r = R[j:, j:]

# Norm of each column
if j == 0:
dlens_old = np.sqrt(np.sum(np.abs(r) ** 2, axis=0))
else:
dlens_old = dlens
dlens = np.sqrt(np.sum(np.abs(r) ** 2, axis=0))
dlens_updated = self._norm_calc_Instance(self.idx_constrained, dlens, p, j, self.n_const_sensors, dlens_old=dlens_old, all_sensors=self.all_sensors, n_sensors=self.n_sensors, nx=self.nx, ny=self.ny, r=self.r)
# i_piv = np.argmax(dlens_updated)
i_piv = np.where(dlens_updated==dlens_updated.max())[0][0]
dlen = dlens_updated[i_piv]

if dlen > 0:
u = r[:, i_piv] / dlen
u[0] += np.sign(u[0]) + (u[0] == 0)
u /= np.sqrt(abs(u[0]))
else:
u = r[:, i_piv]
u[0] = np.sqrt(2)

# Track column pivots
i_piv += j # true permutation index is i_piv shifted by the iteration counter j
p[[j, i_piv]] = p[[i_piv, j]]

# Switch columns
R[:, [j, i_piv]] = R[:, [i_piv, j]]

# Apply reflector
R[j:, j:] -= np.outer(u, np.dot(u, R[j:, j:]))
R[j + 1 :, j] = 0
self.pivots_ = p
return self
3 changes: 2 additions & 1 deletion pysensors/reconstruction/_sspor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from ..basis import Identity
from ..optimizers import CCQR
from ..optimizers import QR
from ..optimizers import GQR
from ..utils import validate_input


Expand Down Expand Up @@ -510,7 +511,7 @@ def _validate_n_sensors(self):
# If n_sensors exceeds n_samples, the cost-constrained QR algorithm may
# place sensors in constrained areas.
if (
isinstance(self.optimizer, CCQR)
isinstance(self.optimizer, CCQR) or isinstance(self.optimizer, QR) or isinstance(self.optimizer, GQR)
and self.n_sensors > self.basis_matrix_.shape[1]
):
warnings.warn(
Expand Down
40 changes: 40 additions & 0 deletions pysensors/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,50 @@
from ._base import validate_input
from ._optimizers import constrained_binary_solve
from ._optimizers import constrained_multiclass_solve
from ._constraints import get_constraind_sensors_indices
from ._constraints import get_constrained_sensors_indices_dataframe
from ._constraints import BaseConstraint
from ._constraints import Circle
from ._constraints import Cylinder
from ._constraints import Line
from ._constraints import Ellipse
from ._constraints import Parabola
from ._constraints import Polygon
from ._constraints import UserDefinedConstraints
from ._constraints import check_constraints
from ._constraints import constraints_eval

from ._constraints import load_functional_constraints
from ._constraints import get_coordinates_from_indices
from ._constraints import get_indices_from_coordinates
from ._norm_calc import exact_n
from ._norm_calc import max_n
from ._norm_calc import predetermined
from ._validation import determinant
from ._validation import relative_reconstruction_error

__all__ = [
"constrained_binary_solve",
"constrained_multiclass_solve",
"validate_input",
"get_constraind_sensors_indices",
"get_constrained_sensors_indices_linear",
"BaseConstraint",
"Circle",
"Cylinder"
"Line",
"Parabola",
"Polygon",
"Ellipse",
"UserDefinedConstraints"
"box_constraints",
"constraints_eval",
"functional_constraints",
"get_coordinates_from_indices",
"get_indices_from_coordinates",
"exact_n",
"max_n",
"predetermined",
"determinant",
"relative_reconstruction_error"
]
Loading