def overlay_grid(self): # overlay a k by k grid on target points f = N.finfo(float) self.max_x = f.min self.max_y = f.min self.min_x = f.max self.min_y = f.max ### print 'max_x: ', self.max_x, ' max_y: ', self.max_y, ' min_x: ', self.min_x, ' min_y: ', self.min_y # find max and min x, y for nn in range(self.n): if self.tgt_x[nn] > self.max_x: self.max_x = self.tgt_x[nn] if self.tgt_y[nn] > self.max_y: self.max_y = self.tgt_y[nn] if self.tgt_x[nn] < self.min_x: self.min_x = self.tgt_x[nn] if self.tgt_y[nn] < self.min_y: self.min_y = self.tgt_y[nn] #-- print 'max_x: ', self.max_x, ' max_y: ', self.max_y, ' min_x: ', self.min_x, ' min_y: ', self.min_y # in the grid, add a layer of width qry_range surrounding all the target points # adjust lon degree span based on lat rR1 = N.cos(U.degree_to_radian(self.max_x)) rR2 = N.cos(U.degree_to_radian(self.min_x)) if rR1 < rR2: rR = rR1 else: rR = rR2 qry_lat_span = self.qry_range * K2D qry_lon_span = qry_lat_span / rR if qry_lon_span > 360.0: print '****** Warning: large lon span ', qry_lon_span print ' Possibly from high latitude target point!' self.min_x -= qry_lat_span self.max_x += qry_lat_span self.min_y -= qry_lon_span self.max_y += qry_lon_span #-- print 'after adjusting with qry_range, max_x: ', self.max_x, ' max_y: ', self.max_y, ' min_x: ', self.min_x, ' min_y: ', self.min_y # overlay a k by k grid dx = (self.max_x - self.min_x) / self.k dy = (self.max_y - self.min_y) / self.k #---print 'dx: ', dx, ' dy: ', dy self.grid_x[0] = self.min_x self.grid_y[0] = self.min_y self.grid_x[self.k] = self.max_x self.grid_y[self.k] = self.max_y for kk in range(1, self.k): self.grid_x[kk] = self.grid_x[kk - 1] + dx self.grid_y[kk] = self.grid_y[kk - 1] + dy ### print 'self.grid_x: ', self.grid_x ### print 'self.grid_y: ', self.grid_y ### print '' # register each target point to a cell (ix, iy) for nn in range(self.n): tgt_x = self.tgt_x[nn] tgt_y = self.tgt_y[nn] # O(log(n)) search """ ix1 = B.bisect(self.grid_x, tgt_x) - 1 if ix1 == self.k: ix1 = self.k - 1 iy1 = B.bisect(self.grid_y, tgt_y) - 1 if iy1 == self.k: iy1 = self.k - 1 """ # O(n) ### print 'self.grid_x: ', self.grid_x ix = self.get_cell_num(self.grid_x, tgt_x) ### print 'self.grid_y: ', self.grid_y iy = self.get_cell_num(self.grid_y, tgt_y) # all target points are in the grid, so no need to check # if nn is outside the grid self.grid_regi[ix][iy].append(nn) """ if ix1 != ix or iy1 != iy: print '****** Warning: nn: ', nn, ' tgt_x: ', tgt_x, ' tgt_y: ', tgt_y print 'ix: ', ix, ' iy: ', iy print 'ix1: ', ix1, ' iy1: ', iy1 """ """ print '------ nn: ', nn, ' tgt_x: ', tgt_x, ' tgt_y: ', tgt_y print 'ix: ', ix, ' iy: ', iy print '' """ ### print self.grid_regi """
def overlay_grid(self): # overlay a k by k grid on target points f = N.finfo(float) self.max_x = f.min self.max_y = f.min self.min_x = f.max self.min_y = f.max ### print 'max_x: ', self.max_x, ' max_y: ', self.max_y, ' min_x: ', self.min_x, ' min_y: ', self.min_y # find max and min x, y for nn in range(self.n): if self.tgt_x[nn] > self.max_x: self.max_x = self.tgt_x[nn] if self.tgt_y[nn] > self.max_y: self.max_y = self.tgt_y[nn] if self.tgt_x[nn] < self.min_x: self.min_x = self.tgt_x[nn] if self.tgt_y[nn] < self.min_y: self.min_y = self.tgt_y[nn] #-- print 'max_x: ', self.max_x, ' max_y: ', self.max_y, ' min_x: ', self.min_x, ' min_y: ', self.min_y # in the grid, add a layer of width qry_range surrounding all the target points # adjust lon degree span based on lat rR1 = N.cos(U.degree_to_radian(self.max_x)) rR2 = N.cos(U.degree_to_radian(self.min_x)) if rR1 < rR2: rR = rR1 else: rR = rR2 qry_lat_span = self.qry_range * K2D qry_lon_span = qry_lat_span / rR if qry_lon_span > 360.0: print '****** Warning: large lon span ', qry_lon_span print ' Possibly from high latitude target point!' self.min_x -= qry_lat_span self.max_x += qry_lat_span self.min_y -= qry_lon_span self.max_y += qry_lon_span #-- print 'after adjusting with qry_range, max_x: ', self.max_x, ' max_y: ', self.max_y, ' min_x: ', self.min_x, ' min_y: ', self.min_y # overlay a k by k grid dx = (self.max_x - self.min_x)/self.k dy = (self.max_y - self.min_y)/self.k #---print 'dx: ', dx, ' dy: ', dy self.grid_x[0] = self.min_x self.grid_y[0] = self.min_y self.grid_x[self.k] = self.max_x self.grid_y[self.k] = self.max_y for kk in range(1, self.k): self.grid_x[kk] = self.grid_x[kk-1] + dx self.grid_y[kk] = self.grid_y[kk-1] + dy ### print 'self.grid_x: ', self.grid_x ### print 'self.grid_y: ', self.grid_y ### print '' # register each target point to a cell (ix, iy) for nn in range(self.n): tgt_x = self.tgt_x[nn] tgt_y = self.tgt_y[nn] # O(log(n)) search """ ix1 = B.bisect(self.grid_x, tgt_x) - 1 if ix1 == self.k: ix1 = self.k - 1 iy1 = B.bisect(self.grid_y, tgt_y) - 1 if iy1 == self.k: iy1 = self.k - 1 """ # O(n) ### print 'self.grid_x: ', self.grid_x ix = self.get_cell_num(self.grid_x, tgt_x) ### print 'self.grid_y: ', self.grid_y iy = self.get_cell_num(self.grid_y, tgt_y) # all target points are in the grid, so no need to check # if nn is outside the grid self.grid_regi[ix][iy].append(nn) """ if ix1 != ix or iy1 != iy: print '****** Warning: nn: ', nn, ' tgt_x: ', tgt_x, ' tgt_y: ', tgt_y print 'ix: ', ix, ' iy: ', iy print 'ix1: ', ix1, ' iy1: ', iy1 """ """ print '------ nn: ', nn, ' tgt_x: ', tgt_x, ' tgt_y: ', tgt_y print 'ix: ', ix, ' iy: ', iy print '' """ ### print self.grid_regi """
def search_nn(self): # search for Nearest Neighbors cnt_dist = 0 # cnt how many dist calculations cnt_no_comp = 0 # cnt how many updates w/o dist calc print '*** in search_nn(), self.qry_idx1, self.qry_idx2+1: ', self.qry_idx1, self.qry_idx2 + 1 elapsed_time1 = datetime.timedelta(0, 0, 0, 0, 0) elapsed_time2 = datetime.timedelta(0, 0, 0, 0, 0) # loop over query points, and find all target points # of which this query point can be NN for mm in range(self.qry_idx1, self.qry_idx2 + 1): ### print '' ### print '------- query point: mm= ', mm, ' ----------' ### print 'x: ', self.qry_x[mm], ' y: ', self.qry_y[mm] ### print 'self.qry_range: ', self.qry_range, ' K2D: ', K2D # check if qry pt mm is outside the grid # if yes, skip this qry point imm = self.get_cell_num(self.grid_x, self.qry_x[mm]) jmm = self.get_cell_num(self.grid_y, self.qry_y[mm]) if imm == NOT_IN_GRID or jmm == NOT_IN_GRID: continue # adjust lon degree span based on lat rR = N.cos(U.degree_to_radian(self.qry_x[mm])) if self.qry_range * K2D / rR > 360.0: print '****** Warning: large lon span ', self.qry_range * K2D / rR print ' Possibly from high latitude query point!' # find Minimum Bounding Rectangular of query point's search range mbr_x_min = self.qry_x[mm] - self.qry_range * K2D if mbr_x_min < self.min_x: # MBR cannot go out of the grid mbr_x_min = self.min_x if mbr_x_min > self.max_x: mbr_x_min = self.max_x mbr_x_max = self.qry_x[mm] + self.qry_range * K2D if mbr_x_max > self.max_x: mbr_x_max = self.max_x if mbr_x_max < self.min_x: mbr_x_max = self.min_x mbr_y_min = self.qry_y[mm] - self.qry_range * K2D / rR if mbr_y_min < self.min_y: mbr_y_min = self.min_y if mbr_y_min > self.max_y: mbr_y_min = self.max_y mbr_y_max = self.qry_y[mm] + self.qry_range * K2D / rR if mbr_y_max > self.max_y: mbr_y_max = self.max_y if mbr_y_max < self.min_y: mbr_y_max = self.min_y # find grid cells that cover the MBR (O(log(n))) """ imin3 = B.bisect(self.grid_x, mbr_x_min) - 1 if imin3 < 0: # handle the boundary point imin3 = 0 if imin3 == self.k: # handle the boundary point imin3 = self.k - 1 imax3 = B.bisect(self.grid_x, mbr_x_max) - 1 if imax3 == self.k: imax3 = self.k - 1 jmin3 = B.bisect(self.grid_y, mbr_y_min) - 1 if jmin3 < 0: jmin3 = 0 if jmin3 == self.k: jmin3 = self.k - 1 jmax3 = B.bisect(self.grid_y, mbr_y_max) - 1 if jmax3 == self.k: jmax3 = self.k - 1 """ # find grid cells that cover the MBR (O(1)) # if MBR outside the grid, the closest cell # on the edge or corner of the grid is found imin = self.get_cell_num(self.grid_x, mbr_x_min) imax = self.get_cell_num(self.grid_x, mbr_x_max) jmin = self.get_cell_num(self.grid_y, mbr_y_min) jmax = self.get_cell_num(self.grid_y, mbr_y_max) # no need to check boundary 'cause the MBR is guaranteed to be inside the grid """ if imin3 != imin or imax3 != imax: ### print 'self.grid_x: ', self.grid_x print '****** Warning: mm: ', mm, ' mbr_x_min: ', mbr_x_min, ' mbr_x_max: ', mbr_x_max print 'imin: ', imin, ' imax: ', imax print 'imin3: ', imin3, ' imax3: ', imax3 if jmin3 != jmin or jmax3 != jmax: print '****** Warning: mm: ', mm, ' mbr_y_min: ', mbr_y_min, ' mbr_y_max: ', mbr_y_max print 'jmin: ', jmin, ' jmax: ', jmax print 'jmin3: ', jmin3, ' jmax3: ', jmax3 """ """ if mm == 133706: print '------ for mm == ', mm print 'imin: ', imin, ' imax: ', imax, ' jmin: ', jmin, ' jmax: ', jmax print 'rR: ', rR """ # choose C by C cells in the center from above imin1 = imin imax1 = imax iex = int((imax - imin - C) / 2) if iex > 0: imin1 = imin + iex imax1 = imin + C jmin1 = jmin jmax1 = jmax jex = int((jmax - jmin - C) / 2) if jex > 0: jmin1 = jmin + jex jmax1 = jmin + C """ if mm == 133706: print '------ for mm == ', mm print 'imin1: ', imin1, ' imax1: ', imax1, ' jmin1: ', jmin1, ' jmax1: ', jmax1 """ # compare and update the NN of target points within C by C cells start1 = datetime.datetime.now() for ii in range(imin1, imax1 + 1): for jj in range(jmin1, jmax1 + 1): len1 = len(self.grid_regi[ii][jj]) ### print 'ii: ', ii, ' jj: ', jj, ' len1: ', len1 # loop over all target points in this cell for ll in range(len1): nn = self.grid_regi[ii][jj][ll] cnt_dist += 1 d = D.get_Haversine_distance(self.tgt_x[nn], self.tgt_y[nn], \ self.qry_x[mm], self.qry_y[mm]) """ print 'nn: ', nn, self.tgt_x[nn], self.tgt_y[nn] print 'mm: ', mm, self.qry_x[mm], self.qry_y[mm] print 'd: ', d, ', self.qry_range: ', self.qry_range """ # this qry point is nearer than previous NN if d < self.qry_range and d < self.nn_dist[nn]: self.nn_dist[nn] = d self.nn_idx[nn] = mm ### print 'nn: ', nn, ', self.nn_dist[nn]: ', self.nn_dist[nn], ', self.nn_idx[nn]: ', self.nn_idx[nn] now1 = datetime.datetime.now() elapsed_time1 += now1 - start1 # update (but not compare) the NN of target points outside C by C # but inside grid cells that cover the MBR start1 = datetime.datetime.now() for ii in range(imin, imax + 1): for jj in range(jmin, jmax + 1): # any cell outside of C by C # if C chosen is large enough to cover the MBR, nothing will be done here if ii < imin1 or ii > imax1 or jj < jmin1 or jj > jmax1: len1 = len(self.grid_regi[ii][jj]) """ print '------ (no dist calc) mm == ', mm print 'imin: ', imin, ' imax: ', imax, ' jmin: ', jmin, ' jmax: ', jmax print 'imin1: ', imin1, ' imax1: ', imax1, ' jmin1: ', jmin1, ' jmax1: ', jmax1 print 'ii: ', ii, ' jj: ', jj, ' len1: ', len1 """ # loop over all target points in this cell for ll in range(len1): nn = self.grid_regi[ii][jj][ll] if self.nn_idx[ nn] == NOT_NN: # this tgt pt hasn't got a NN yet cnt_no_comp += 1 self.nn_idx[nn] = mm now1 = datetime.datetime.now() elapsed_time2 += now1 - start1 # end of for mm print 'in search_nn, self.nn_idx: ', self.nn_idx print 'self.nn_dist: ', self.nn_dist print 'cnt dist calculation: ', cnt_dist, ' cnt in footprint but w/o dist calc: ', cnt_no_comp print 'elapsed_time1: ', elapsed_time1 print '*** compare and update elapsed time: ', elapsed_time1.days, ' days, ', elapsed_time1.seconds, ' seconds' print 'elapsed_time2: ', elapsed_time2 print '*** update only elapsed time: ', elapsed_time2.days, ' days, ', elapsed_time2.seconds, ' seconds' return (self.nn_idx, self.nn_dist)
def search_nn(self): # search for Nearest Neighbors cnt_dist = 0 # cnt how many dist calculations cnt_no_comp = 0 # cnt how many updates w/o dist calc print '*** in search_nn(), self.qry_idx1, self.qry_idx2+1: ', self.qry_idx1, self.qry_idx2+1 elapsed_time1 = datetime.timedelta(0,0,0,0,0) elapsed_time2 = datetime.timedelta(0,0,0,0,0) # loop over query points, and find all target points # of which this query point can be NN for mm in range(self.qry_idx1, self.qry_idx2+1): ### print '' ### print '------- query point: mm= ', mm, ' ----------' ### print 'x: ', self.qry_x[mm], ' y: ', self.qry_y[mm] ### print 'self.qry_range: ', self.qry_range, ' K2D: ', K2D # check if qry pt mm is outside the grid # if yes, skip this qry point imm = self.get_cell_num(self.grid_x, self.qry_x[mm]) jmm = self.get_cell_num(self.grid_y, self.qry_y[mm]) if imm == NOT_IN_GRID or jmm == NOT_IN_GRID: continue # adjust lon degree span based on lat rR = N.cos(U.degree_to_radian(self.qry_x[mm])) if self.qry_range * K2D / rR > 360.0: print '****** Warning: large lon span ', self.qry_range * K2D / rR print ' Possibly from high latitude query point!' # find Minimum Bounding Rectangular of query point's search range mbr_x_min = self.qry_x[mm] - self.qry_range * K2D if mbr_x_min < self.min_x: # MBR cannot go out of the grid mbr_x_min = self.min_x if mbr_x_min > self.max_x: mbr_x_min = self.max_x mbr_x_max = self.qry_x[mm] + self.qry_range * K2D if mbr_x_max > self.max_x: mbr_x_max = self.max_x if mbr_x_max < self.min_x: mbr_x_max = self.min_x mbr_y_min = self.qry_y[mm] - self.qry_range * K2D / rR if mbr_y_min < self.min_y: mbr_y_min = self.min_y if mbr_y_min > self.max_y: mbr_y_min = self.max_y mbr_y_max = self.qry_y[mm] + self.qry_range * K2D / rR if mbr_y_max > self.max_y: mbr_y_max = self.max_y if mbr_y_max < self.min_y: mbr_y_max = self.min_y # find grid cells that cover the MBR (O(log(n))) """ imin3 = B.bisect(self.grid_x, mbr_x_min) - 1 if imin3 < 0: # handle the boundary point imin3 = 0 if imin3 == self.k: # handle the boundary point imin3 = self.k - 1 imax3 = B.bisect(self.grid_x, mbr_x_max) - 1 if imax3 == self.k: imax3 = self.k - 1 jmin3 = B.bisect(self.grid_y, mbr_y_min) - 1 if jmin3 < 0: jmin3 = 0 if jmin3 == self.k: jmin3 = self.k - 1 jmax3 = B.bisect(self.grid_y, mbr_y_max) - 1 if jmax3 == self.k: jmax3 = self.k - 1 """ # find grid cells that cover the MBR (O(1)) # if MBR outside the grid, the closest cell # on the edge or corner of the grid is found imin = self.get_cell_num(self.grid_x, mbr_x_min) imax = self.get_cell_num(self.grid_x, mbr_x_max) jmin = self.get_cell_num(self.grid_y, mbr_y_min) jmax = self.get_cell_num(self.grid_y, mbr_y_max) # no need to check boundary 'cause the MBR is guaranteed to be inside the grid """ if imin3 != imin or imax3 != imax: ### print 'self.grid_x: ', self.grid_x print '****** Warning: mm: ', mm, ' mbr_x_min: ', mbr_x_min, ' mbr_x_max: ', mbr_x_max print 'imin: ', imin, ' imax: ', imax print 'imin3: ', imin3, ' imax3: ', imax3 if jmin3 != jmin or jmax3 != jmax: print '****** Warning: mm: ', mm, ' mbr_y_min: ', mbr_y_min, ' mbr_y_max: ', mbr_y_max print 'jmin: ', jmin, ' jmax: ', jmax print 'jmin3: ', jmin3, ' jmax3: ', jmax3 """ """ if mm == 133706: print '------ for mm == ', mm print 'imin: ', imin, ' imax: ', imax, ' jmin: ', jmin, ' jmax: ', jmax print 'rR: ', rR """ # choose C by C cells in the center from above imin1 = imin; imax1 = imax iex = int((imax - imin - C)/2) if iex > 0: imin1 = imin + iex imax1 = imin + C jmin1 = jmin; jmax1 = jmax jex = int((jmax - jmin - C)/2) if jex > 0: jmin1 = jmin + jex jmax1 = jmin + C """ if mm == 133706: print '------ for mm == ', mm print 'imin1: ', imin1, ' imax1: ', imax1, ' jmin1: ', jmin1, ' jmax1: ', jmax1 """ # compare and update the NN of target points within C by C cells start1 = datetime.datetime.now() for ii in range(imin1, imax1+1): for jj in range(jmin1, jmax1+1): len1 = len(self.grid_regi[ii][jj]) ### print 'ii: ', ii, ' jj: ', jj, ' len1: ', len1 # loop over all target points in this cell for ll in range(len1): nn = self.grid_regi[ii][jj][ll] cnt_dist += 1 d = D.get_Haversine_distance(self.tgt_x[nn], self.tgt_y[nn], \ self.qry_x[mm], self.qry_y[mm]) """ print 'nn: ', nn, self.tgt_x[nn], self.tgt_y[nn] print 'mm: ', mm, self.qry_x[mm], self.qry_y[mm] print 'd: ', d, ', self.qry_range: ', self.qry_range """ # this qry point is nearer than previous NN if d < self.qry_range and d < self.nn_dist[nn]: self.nn_dist[nn] = d self.nn_idx[nn] = mm ### print 'nn: ', nn, ', self.nn_dist[nn]: ', self.nn_dist[nn], ', self.nn_idx[nn]: ', self.nn_idx[nn] now1 = datetime.datetime.now() elapsed_time1 += now1 - start1 # update (but not compare) the NN of target points outside C by C # but inside grid cells that cover the MBR start1 = datetime.datetime.now() for ii in range(imin, imax+1): for jj in range(jmin, jmax+1): # any cell outside of C by C # if C chosen is large enough to cover the MBR, nothing will be done here if ii < imin1 or ii > imax1 or jj < jmin1 or jj > jmax1: len1 = len(self.grid_regi[ii][jj]) """ print '------ (no dist calc) mm == ', mm print 'imin: ', imin, ' imax: ', imax, ' jmin: ', jmin, ' jmax: ', jmax print 'imin1: ', imin1, ' imax1: ', imax1, ' jmin1: ', jmin1, ' jmax1: ', jmax1 print 'ii: ', ii, ' jj: ', jj, ' len1: ', len1 """ # loop over all target points in this cell for ll in range(len1): nn = self.grid_regi[ii][jj][ll] if self.nn_idx[nn] == NOT_NN: # this tgt pt hasn't got a NN yet cnt_no_comp += 1 self.nn_idx[nn] = mm now1 = datetime.datetime.now() elapsed_time2 += now1 - start1 # end of for mm print 'in search_nn, self.nn_idx: ', self.nn_idx print 'self.nn_dist: ', self.nn_dist print 'cnt dist calculation: ', cnt_dist, ' cnt in footprint but w/o dist calc: ', cnt_no_comp print 'elapsed_time1: ', elapsed_time1 print '*** compare and update elapsed time: ', elapsed_time1.days, ' days, ', elapsed_time1.seconds, ' seconds' print 'elapsed_time2: ', elapsed_time2 print '*** update only elapsed time: ', elapsed_time2.days, ' days, ', elapsed_time2.seconds, ' seconds' return (self.nn_idx, self.nn_dist)