Coverage for src / zooc / dsp / surface_nearest_interpolator.py: 0%
40 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 21:45 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 21:45 +0000
1"""2D-surface with interpolation and extrapolation using simple nearest neighbor interpolation."""
2import bisect
3from collections import OrderedDict
4from functools import cached_property
6import numpy as np
7import numpy.typing as npt
8from typing_extensions import deprecated
11@deprecated("Not supported")
12class SurfaceNearestInterpolator:
13 """Simple Nearest interpolator without numpy dependency.
15 .. deprecated:: 1.0
16 This module is obsolete.
18 For now, the module still uses numpy.
19 """
21 @staticmethod
22 def nearest[T](dict_v: dict[float, T], key_value: float) -> T:
23 """Search the dict value of which key is nearest to given key.
25 When the target key is exactly between the two keys, select the larger one.
27 :param dict_v: Dict with float keys and any value. Keys must be sorted in ascending order.
28 :param key_value: Target key value to search.
29 :return: Value of the nearest key to target.
30 """
31 list_keys = list(dict_v.keys())
32 list_keys = sorted(list_keys)
33 index_nearest_max = bisect.bisect_left(list_keys, key_value)
34 if index_nearest_max >= len(list_keys):
35 index_nearest_max -= 1
36 if index_nearest_max == 0:
37 return dict_v[list_keys[index_nearest_max]]
39 key_max = list_keys[index_nearest_max]
40 key_min = list_keys[index_nearest_max - 1]
41 if key_value - key_min < key_max - key_value:
42 return dict_v[key_min]
43 return dict_v[key_max]
45 def __init__(self, xy: tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]], z: npt.NDArray[np.float64]) -> None:
46 """Nearest interpolation without numpy.
48 :param xy: XY-coordinates as a tuple of two numpy arrays (x, y).
49 :param z: Z-coordinates as a numpy array.
50 """
51 self.xy = xy
52 self.z = z
54 @cached_property
55 def dict_x(self) -> dict[float, dict[float, float]]:
56 """Create a dictionary of x-coordinates with z-coordinates as values.
58 :return: Dictionary with x-coordinates as keys and z-coordinates as values.
59 """
60 dict_x: dict[float, dict[float, float]] = OrderedDict()
61 for xy, z in zip(self.xy, self.z, strict=True):
62 dict_e_z = dict_x.setdefault(float(xy[0]), OrderedDict())
63 dict_e_z[float(xy[1])] = z
64 return dict_x
66 def __call__(self, xx: npt.NDArray[np.float64], yy: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]:
67 """Solve the nearest interpolation for given x and y coordinates.
69 :param xx: X coordinates.
70 :param yy: Y coordinates.
71 :return: Z values at given x, y coordinates.
72 """
73 output_xx = np.full_like(xx, 0)
74 for ix, x in np.ndenumerate(xx):
75 y = float(yy[ix])
76 # noinspection PyDeprecation
77 dict_e_nearest: dict[float, float] = SurfaceNearestInterpolator.nearest(self.dict_x, x)
78 # noinspection PyDeprecation
79 value = SurfaceNearestInterpolator.nearest(dict_e_nearest, y)
80 output_xx[ix] = value
81 return output_xx