Skip to content

Commit ab4bdbd

Browse files
author
niharika2999
committed
Moving norm_calculation functions to utilities
1 parent 69a5511 commit ab4bdbd

File tree

3 files changed

+217
-127
lines changed

3 files changed

+217
-127
lines changed

pysensors/optimizers/_gqr.py

Lines changed: 52 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from mpl_toolkits.axes_grid1 import make_axes_locatable
99

1010
import pysensors as ps
11+
from matplotlib.patches import Circle
1112

1213

1314
class GQR(QR):
@@ -27,7 +28,7 @@ class GQR(QR):
2728
2829
@ authors: Niharika Karnik (@nkarnik2999), Mohammad Abdo (@Jimmy-INL), and Krithika Manohar (@kmanohar)
2930
"""
30-
def __init__(self,idx_constrained,n_sensors,n_const_sensors,all_sensors,constraint_option):
31+
def __init__(self,idx_constrained,n_sensors,n_const_sensors,all_sensors,constraint_option,nx,ny,r):
3132
"""
3233
Attributes
3334
----------
@@ -47,11 +48,15 @@ def __init__(self,idx_constrained,n_sensors,n_const_sensors,all_sensors,constrai
4748
"""
4849
self.pivots_ = None
4950
self.optimality = None
51+
5052
self.constrainedIndices = idx_constrained
5153
self.nSensors = n_sensors
5254
self.nConstrainedSensors = n_const_sensors
5355
self.all_sensorloc = all_sensors
5456
self.constraint_option = constraint_option
57+
self._nx = nx
58+
self._ny = ny
59+
self._r = r
5560

5661
def fit(
5762
self,
@@ -92,16 +97,33 @@ def fit(
9297
# Norm of each column
9398
dlens = np.sqrt(np.sum(np.abs(r) ** 2, axis=0))
9499
if self.constraint_option == "max_n_const_sensors" :
95-
dlens_updated = norm_calc_max_n_const_sensors(self.constrainedIndices,dlens,p,j, self.nConstrainedSensors,self.all_sensorloc,self.nSensors)
100+
dlens_updated = ps.utils._norm_calc.norm_calc_max_n_const_sensors(self.constrainedIndices,dlens,p,j, self.nConstrainedSensors,self.all_sensorloc,self.nSensors)
101+
i_piv = np.argmax(dlens_updated)
102+
dlen = dlens_updated[i_piv]
96103
elif self.constraint_option == "exact_n_const_sensors" :
97-
dlens_updated = norm_calc_exact_n_const_sensors(self.constrainedIndices,dlens,p,j,self.nConstrainedSensors)
104+
dlens_updated = ps.utils._norm_calc.norm_calc_exact_n_const_sensors(self.constrainedIndices,dlens,p,j,self.nConstrainedSensors)
105+
i_piv = np.argmax(dlens_updated)
106+
dlen = dlens_updated[i_piv]
98107
elif self.constraint_option == "predetermined_end":
99-
dlens_updated = predetermined_norm_calc(self.constrainedIndices, dlens, p, j, self.nConstrainedSensors, self.nSensors)
108+
dlens_updated = ps.utils._norm_calc.predetermined_norm_calc(self.constrainedIndices, dlens, p, j, self.nConstrainedSensors, self.nSensors)
109+
i_piv = np.argmax(dlens_updated)
110+
dlen = dlens_updated[i_piv]
111+
elif self.constraint_option == "radii_constraints":
112+
if j == 0:
113+
dlens_old = dlens
114+
i_piv = np.argmax(dlens)
115+
dlen = dlens[i_piv]
116+
else:
117+
118+
dlens_updated = ps.utils._norm_calc.f_radii_constraint(j,dlens,dlens_old,p,self._nx,self._ny,self._r) #( self.radius,self._nx,self._ny,self.all_sensorloc,dlens,p,j)
119+
i_piv = np.argmax(dlens_updated)
120+
dlen = dlens_updated[i_piv]
121+
dlens_old = dlens_updated
100122

101123
# Choose pivot
102-
i_piv = np.argmax(dlens_updated)
124+
# i_piv = np.argmax(dlens_updated)
103125

104-
dlen = dlens_updated[i_piv]
126+
# dlen = dlens_updated[i_piv]
105127

106128
if dlen > 0:
107129
u = r[:, i_piv] / dlen
@@ -128,116 +150,6 @@ def fit(
128150

129151
return self
130152

131-
## TODO: why not a part of the class?
132-
133-
#function for mapping sensor locations with constraints
134-
def norm_calc_exact_n_const_sensors(lin_idx, dlens, piv, j, n_const_sensors): ##Will first force sensors into constrained region
135-
#num_sensors should be fixed for each custom constraint (for now)
136-
#num_sensors must be <= size of constraint region
137-
"""
138-
Function for mapping constrained sensor locations with the QR procedure.
139-
140-
Parameters
141-
----------
142-
lin_idx: np.ndarray, shape [No. of constrained locations]
143-
Array which contains the constrained locationsof the grid in terms of column indices of basis_matrix.
144-
dlens: np.ndarray, shape [Variable based on j]
145-
Array which contains the norm of columns of basis matrix.
146-
piv: np.ndarray, shape [n_features]
147-
Ranked list of sensor locations.
148-
n_const_sensors: int,
149-
Number of sensors to be placed in the constrained area.
150-
j: int,
151-
Iterative variable in the QR algorithm.
152-
153-
Returns
154-
-------
155-
dlens : np.darray, shape [Variable based on j] with constraints mapped into it.
156-
"""
157-
if j < n_const_sensors: # force sensors into constraint region
158-
#idx = np.arange(dlens.shape[0])
159-
#dlens[np.delete(idx, lin_idx)] = 0
160-
161-
didx = np.isin(piv[j:],lin_idx,invert=True)
162-
dlens[didx] = 0
163-
else:
164-
didx = np.isin(piv[j:],lin_idx,invert=False)
165-
dlens[didx] = 0
166-
return dlens
167-
168-
def norm_calc_max_n_const_sensors(lin_idx, dlens, piv, j, const_sensors,all_sensors,n_sensors): ##Optimal sensor placement with constraints (will place sensors in the order of QR)
169-
"""
170-
Function for mapping constrained sensor locations with the QR procedure (Optimally).
171-
172-
Parameters
173-
----------
174-
lin_idx: np.ndarray, shape [No. of constrained locations]
175-
Array which contains the constrained locationsof the grid in terms of column indices of basis_matrix.
176-
dlens: np.ndarray, shape [Variable based on j]
177-
Array which contains the norm of columns of basis matrix.
178-
piv: np.ndarray, shape [n_features]
179-
Ranked list of sensor locations.
180-
j: int,
181-
Iterative variable in the QR algorithm.
182-
const_sensors: int,
183-
Number of sensors to be placed in the constrained area.
184-
all_sensors: np.ndarray, shape [n_features]
185-
Ranked list of sensor locations.
186-
n_sensors: integer,
187-
Total number of sensors
188-
189-
Returns
190-
-------
191-
dlens : np.darray, shape [Variable based on j] with constraints mapped into it.
192-
"""
193-
counter = 0
194-
mask = np.isin(all_sensors,lin_idx,invert=False)
195-
const_idx = all_sensors[mask]
196-
updated_lin_idx = const_idx[const_sensors:]
197-
for i in range(n_sensors):
198-
if np.isin(all_sensors[i],lin_idx,invert=False):
199-
counter += 1
200-
if counter < const_sensors:
201-
dlens = dlens
202-
else:
203-
didx = np.isin(piv[j:],updated_lin_idx,invert=False)
204-
dlens[didx] = 0
205-
return dlens
206-
207-
def predetermined_norm_calc(lin_idx, dlens, piv, j, n_const_sensors, n_sensors):
208-
"""
209-
Function for mapping constrained sensor locations with the QR procedure.
210-
211-
Parameters
212-
----------
213-
lin_idx: np.ndarray, shape [No. of constrained locations]
214-
Array which contains the constrained locationsof the grid in terms of column indices of basis_matrix.
215-
dlens: np.ndarray, shape [Variable based on j]
216-
Array which contains the norm of columns of basis matrix.
217-
piv: np.ndarray, shape [n_features]
218-
Ranked list of sensor locations.
219-
n_const_sensors: int,
220-
Number of sensors to be placed in the constrained area.
221-
j: int,
222-
Iterative variable in the QR algorithm.
223-
224-
Returns
225-
-------
226-
dlens : np.darray, shape [Variable based on j] with constraints mapped into it.
227-
"""
228-
if (n_sensors - n_const_sensors) <= j <= n_sensors: # force sensors into constraint region
229-
#idx = np.arange(dlens.shape[0])
230-
#dlens[np.delete(idx, lin_idx)] = 0
231-
232-
didx = np.isin(piv[j:],lin_idx,invert=True)
233-
dlens[didx] = 0
234-
else:
235-
didx = np.isin(piv[j:],lin_idx,invert=False)
236-
dlens[didx] = 0
237-
return dlens
238-
239-
240-
241153
if __name__ == '__main__':
242154
faces = datasets.fetch_olivetti_faces(shuffle=True)
243155
X = faces.data
@@ -277,8 +189,9 @@ def plot_gallery(title, images, n_col=n_col, n_row=n_row, cmap=plt.cm.gray):
277189
#Find all sensor locations using built in QR optimizer
278190
#max_const_sensors = 230
279191
n_const_sensors = 3
280-
n_sensors = 10
281-
n_modes = 11
192+
n_sensors = 30
193+
n_modes = 50
194+
r = 5
282195
basis = ps.basis.SVD(n_basis_modes=n_modes)
283196
optimizer = ps.optimizers.QR()
284197
model = ps.SSPOR(basis = basis, optimizer=optimizer, n_sensors=n_sensors)
@@ -311,7 +224,7 @@ def plot_gallery(title, images, n_col=n_col, n_row=n_row, cmap=plt.cm.gray):
311224
# plt.title('Constrained region');
312225

313226
## Fit the dataset with the optimizer GQR
314-
optimizer1 = GQR(sensors_constrained,n_sensors,n_const_sensors,all_sensors, constraint_option = "exact_n_const_sensors")
227+
optimizer1 = GQR(sensors_constrained,n_sensors,n_const_sensors,all_sensors, constraint_option = "radii_constraints",nx = nx, ny = ny, r = r)
315228
model1 = ps.SSPOR(basis = basis, optimizer = optimizer1, n_sensors = n_sensors)
316229
model1.fit(X)
317230
all_sensors1 = model1.get_all_sensors()
@@ -322,13 +235,26 @@ def plot_gallery(title, images, n_col=n_col, n_row=n_row, cmap=plt.cm.gray):
322235
#yConstrained = np.floor(top_sensors[:n_const_sensors]/np.sqrt(n_features))
323236
#xConstrained = np.mod(top_sensors[:n_const_sensors],np.sqrt(n_features))
324237

238+
# img = np.zeros(n_features)
239+
# img[top_sensors] = 16
240+
# #plt.plot(xConstrained,yConstrained,'*r')
241+
# plt.plot([xmin,xmin],[ymin,ymax],'r')
242+
# plt.plot([xmin,xmax],[ymax,ymax],'r')
243+
# plt.plot([xmax,xmax],[ymin,ymax],'r')
244+
# plt.plot([xmin,xmax],[ymin,ymin],'r')
245+
# plt.imshow(img.reshape(image_shape),cmap=plt.cm.binary)
246+
# plt.title('n_sensors = {}, n_constr_sensors = {}'.format(n_sensors,n_const_sensors))
247+
# plt.show()
248+
325249
img = np.zeros(n_features)
326250
img[top_sensors] = 16
327-
#plt.plot(xConstrained,yConstrained,'*r')
328-
plt.plot([xmin,xmin],[ymin,ymax],'r')
329-
plt.plot([xmin,xmax],[ymax,ymax],'r')
330-
plt.plot([xmax,xmax],[ymin,ymax],'r')
331-
plt.plot([xmin,xmax],[ymin,ymin],'r')
332-
plt.imshow(img.reshape(image_shape),cmap=plt.cm.binary)
333-
plt.title('n_sensors = {}, n_constr_sensors = {}'.format(n_sensors,n_const_sensors))
251+
fig,ax = plt.subplots(1)
252+
ax.set_aspect('equal')
253+
ax.imshow(img.reshape(image_shape),cmap=plt.cm.binary)
254+
print(top_sensors)
255+
top_sensors_grid = np.unravel_index(top_sensors, (nx,ny))
256+
# figure, axes = plt.subplots()
257+
for i in range(len(top_sensors_grid[0])):
258+
circ = Circle( (top_sensors_grid[1][i], top_sensors_grid[0][i]), r ,color='r',fill = False )
259+
ax.add_patch(circ)
334260
plt.show()

pysensors/utils/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
from ._constraints import functional_constraints
88
from ._validation import determinant
99
from ._validation import relative_reconstruction_error
10+
from ._norm_calc import norm_calc_exact_n_const_sensors
11+
from ._norm_calc import norm_calc_max_n_const_sensors
12+
from ._norm_calc import predetermined_norm_calc
13+
from ._norm_calc import f_radii_constraint
1014

1115
__all__ = [
1216
"constrained_binary_solve",
@@ -17,5 +21,9 @@
1721
"box_constraints",
1822
"functional_constraints",
1923
"determinant",
20-
"relative_reconstruction_error"
24+
"relative_reconstruction_error",
25+
"norm_calc_exact_n_const_sensors",
26+
"norm_calc_max_n_const_sensors",
27+
"predetermined_norm_calc",
28+
"f_radii_constraint"
2129
]

0 commit comments

Comments
 (0)