LUT_2D#
Description#
The uz_LUT_2D module provides a 2D look-up table with binary search, bilinear interpolation and value clamping.
It uses the uz_array_float_t type from Array for both breakpoint vectors and flattened data storage.
The breakpoint arrays for x-axis and y-axis must both be strictly increasing (no duplicates) and contain at least two entries.
The flattened data array must be in row-major order (x-index changes fastest), and must have
breakpoints_x.length * breakpoints_y.length entries.
Data indexing of the flattened array follows:
where \(N_x\) is the number of x-axis breakpoints.
For the code example below with LUT_breakpoints_x_array = {0, 1, 2},
LUT_breakpoints_y_array = {0, 1, 2}, and
LUT_data_array = {0, 1, 2, 10, 11, 12, 20, 21, 22}, the row-major flattening is:
x |
y |
row-major index |
lut_data |
|---|---|---|---|
0 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
2 |
0 |
2 |
2 |
0 |
1 |
3 |
10 |
1 |
1 |
4 |
11 |
2 |
1 |
5 |
12 |
0 |
2 |
6 |
20 |
1 |
2 |
7 |
21 |
2 |
2 |
8 |
22 |
If input_x or input_y is outside the breakpoint range, it is clamped to the nearest breakpoint.
The return value is then computed with bilinear interpolation.
If either input is NaN, the return value is also NaN.
// Axis breakpoints
static float LUT_breakpoints_x_array[3] = {0.0f, 1.0f, 2.0f};
static float LUT_breakpoints_y_array[3] = {0.0f, 1.0f, 2.0f};
// Flattened data in row-major order:
// row y=0: {0, 1, 2}
// row y=1: {10, 11, 12}
// row y=2: {20, 21, 22}
static float LUT_data_array[9] = {
0.0f, 1.0f, 2.0f,
10.0f, 11.0f, 12.0f,
20.0f, 21.0f, 22.0f
};
uz_array_float_t LUT_breakpoints_x = {
.length = UZ_ARRAY_SIZE(LUT_breakpoints_x_array),
.data = &LUT_breakpoints_x_array[0]
};
uz_array_float_t LUT_breakpoints_y = {
.length = UZ_ARRAY_SIZE(LUT_breakpoints_y_array),
.data = &LUT_breakpoints_y_array[0]
};
uz_array_float_t LUT_data = {
.length = UZ_ARRAY_SIZE(LUT_data_array),
.data = &LUT_data_array[0]
};
uz_LUT_2D_t *lut_instance = uz_LUT_2D_init(&LUT_breakpoints_x, &LUT_breakpoints_y, &LUT_data);
float input_x = 0.5f;
float input_y = 0.5f;
float output = uz_LUT_2D_get_value(lut_instance, input_x, input_y); // output = 5.5
The following plot shows the LUT support points, the underlying surface grid, and one interpolation point.

Fig. 371 Example 2D LUT support grid for LUT_data_array. The red marker indicates \((x,y)=(0.5,0.5)\) with bilinear interpolation result \(f(0.5,0.5)=5.5\).
Reference#
-
typedef struct uz_LUT_2D_t uz_LUT_2D_t#
-
uz_LUT_2D_t *uz_LUT_2D_init(uz_array_float_t *breakpoints_x, uz_array_float_t *breakpoints_y, uz_array_float_t *data)#
Initializes a 2D Look-Up Table (LUT) instance with the provided breakpoints and grid data.
Data layout:
data is a flattened 2D array in row-major order
x-axis changes fastest
index = (y_index * breakpoints_x->length) + x_index
Preconditions:
breakpoints_x, breakpoints_y and data are not NULL
their data pointers are not NULL
both breakpoint arrays have length of at least 2
both breakpoint arrays are strictly increasing (no duplicates)
data length is breakpoints_x->length * breakpoints_y->length
- Parameters:
breakpoints_x – pointer to x-axis breakpoints
breakpoints_y – pointer to y-axis breakpoints
data – pointer to flattened 2D grid values
- Returns:
uz_LUT_2D_t*
-
float uz_LUT_2D_get_value(uz_LUT_2D_t *self, float input_x, float input_y)#
Returns a bilinearly interpolated LUT value at (input_x, input_y).
Inputs are clamped to the breakpoint ranges before interpolation. NaN inputs propagate through the interpolation and result in NaN.
- Parameters:
self – instance of the LUT_2D
input_x – x-axis input value
input_y – y-axis input value
- Returns:
float