@@ -9,75 +9,89 @@ def __init__(self, logger):
99
1010 def get_nearest_neighbor_indices_local (
1111 self ,
12- all_local_coords ,
13- inter_point ,
12+ all_local_coords : np . ndarray ,
13+ inter_point : np . ndarray ,
1414 k : int ,
15- inter_point_is_neighbor : bool = False ,
1615 ) -> np .ndarray :
1716 """
1817 Get the indices of the k nearest neighbors of a point in a list of coordinates.
19- Note: It can be chosen whether the point itself is considered as a neighbor or not.
20- Args:
21- all_local_coords: list
22- List of coordinates of all points.
23- inter_point:
24- Coordinates of the point for which the neighbors are to be found.
25- k: int
26- inter_point_is_neighbor: bool, optional
27- Decide whether the interpolation point is considered as its own neighbor.
28- Defaults to False.
18+ If inter_point is part of all_local_coords, it is only considered one time less than it occurs.
19+ inter_point is expected to be in all_local_coords at most once.
2920
30- Returns: np.ndarray
31- of indices of the k nearest neighbors.
21+ Parameters
22+ ----------
23+ all_local_coords : list
24+ List of coordinates of all points.
25+ inter_point : list | np.ndarray
26+ Coordinates of the point for which the neighbors are to be found.
27+ k : int
28+ Number of neighbors to consider.
29+
30+ Returns
31+ ------
32+ neighbor_indices : np.ndarray
33+ Indices of the k nearest neighbors in all local points.
3234 """
3335 assert (
34- len (all_local_coords ) > k
35- ), "Desired number of neighbors must be less than the number of all available neighbors."
36- if not inter_point_is_neighbor :
37- neighbors = NearestNeighbors (n_neighbors = k + 1 ).fit (all_local_coords )
36+ len (all_local_coords ) >= k
37+ ), "Desired number of neighbors must be less than or equal to the number of all available neighbors."
38+ # If the number of neighbors is larger than the number of all available neighbors, increase the number of neighbors
39+ # to be able to delete a neighbor if it coincides with the interpolation point.
40+ if len (all_local_coords ) > k :
41+ k += 1
42+ neighbors = NearestNeighbors (n_neighbors = k ).fit (all_local_coords )
3843
39- dists , neighbor_indices = neighbors .kneighbors (
40- [inter_point ], return_distance = True
41- )
44+ dists , neighbor_indices = neighbors .kneighbors (
45+ [inter_point ], return_distance = True
46+ )
4247
43- if np . min ( dists ) < 1e-10 :
44- argmin = np .argmin (dists )
45- neighbor_indices = np .delete ( neighbor_indices , argmin )
46- else :
47- argmax = np . argmax ( dists )
48- neighbor_indices = np . delete ( neighbor_indices , argmax )
48+ # Check whether the inter_point is also part of the neighbor list and remove it.
49+ if np .min (dists ) < 1e-16 :
50+ argmin = np .argmin ( dists )
51+ neighbor_indices = np . delete ( neighbor_indices , argmin )
52+ # If point itself is not in neighbor list, remove neighbor with largest distance
53+ # to return the desired number of neighbors
4954 else :
50- neighbors = NearestNeighbors (n_neighbors = k ).fit (all_local_coords )
51- neighbor_indices = neighbors .kneighbors (
52- [inter_point ], return_distance = False
53- )
55+ argmax = np .argmax (dists )
56+ neighbor_indices = np .delete (neighbor_indices , argmax )
5457
5558 return neighbor_indices
5659
5760 def inv_dist_weighted_interp (
58- self , neighbors : list , point , values : list
59- ) -> np . ndarray :
61+ self , neighbors : np . ndarray , point : np . ndarray , values
62+ ):
6063 """
6164 Interpolate a value at a point using inverse distance weighting.
65+ .. math::
66+ f(x) = (\sum_{i=1}^{n} \f rac{f_i}{\Vert x_i - x \Vert^2}) / (\sum_{j=1}^{n} \f rac{1}{\Vert x_j - x \Vert^2})
6267
63- Args:
64- neighbors: list
65- Coordinates at which the values are known.
66- point:
67- Coordinates at which the value is to be interpolated.
68- values: list
69- Values at the known coordinates.
68+ Parameters
69+ ----------
70+ neighbors : np.ndarray
71+ Coordinates at which the values are known.
72+ point : np.ndarray
73+ Coordinates at which the value is to be interpolated.
74+ values :
75+ Values at the known coordinates.
7076
71- Returns: nd.array
77+ Returns
78+ -------
79+ interpol_val / summed_weights :
7280 Value at interpolation point.
7381 """
7482 interpol_val = 0
7583 summed_weights = 0
84+ # iterate over all neighbors
7685 for inx in range (len (neighbors )):
86+ # compute the squared norm of the difference between interpolation point and neighbor
7787 norm = np .linalg .norm (np .array (neighbors [inx ]) - np .array (point )) ** 2
78- if norm < 1e-10 :
88+ # If interpolation point is already part of the data it is returned as the interpolation result
89+ # This avoids division by zero
90+ if norm < 1e-16 :
7991 return values [inx ]
92+ # update interpolation value
8093 interpol_val += values [inx ] / norm
94+ # extend normalization factor
8195 summed_weights += 1 / norm
8296
8397 return interpol_val / summed_weights
0 commit comments