10#ifndef SEMF_UTILS_PROCESSING_LINEARINTERPOLATOR_H_
11#define SEMF_UTILS_PROCESSING_LINEARINTERPOLATOR_H_
30template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET = T_IN,
typename T_STORAGE = T_TARGET>
52 bool init(
const T_IN dimension1Data[], uint16_t dimension1DataSize,
const T_TARGET targetData[], uint16_t targetDataSize);
65 bool init(
const T_IN dimension1Data[], uint16_t dimension1DataSize,
const T_IN dimension2Data[], uint16_t dimension2DataSize,
const T_TARGET targetData[],
66 uint16_t targetDataSize);
81 bool init(
const T_IN dimension1Data[], uint16_t dimension1DataSize,
const T_IN dimension2Data[], uint16_t dimension2DataSize,
const T_IN dimension3Data[],
82 uint16_t dimension3DataSize,
const T_TARGET targetData[], uint16_t targetDataSize);
106 bool interpolate(T_TARGET& y, T_IN x1 = 0, T_IN x2 = 0, T_IN x3 = 0);
112 void interpolateInOneDimension();
117 void interpolateInTwoDimensions();
122 void interpolateInThreeDimensions();
127 void calculateNeighboringPoints();
132 void getPointIndecies();
137 void checkDimensionBoundaries();
144 T_STORAGE abs(T_STORAGE);
147 bool m_limitToBoundaryValues;
149 T_STORAGE m_partition = 0;
151 const T_IN* m_dim[MAX_DIMENSIONS] = {
nullptr};
153 const T_TARGET* m_targetData =
nullptr;
156 bool m_dimReduction[MAX_DIMENSIONS] = {
true};
158 uint8_t m_consideredDimCtr = 0;
160 uint16_t m_dimLen[MAX_DIMENSIONS] = {0};
162 uint16_t m_targetDataSize = 0;
165 int16_t m_iSVec[MAX_DIMENSIONS] = {-1};
167 int16_t m_iBVec[MAX_DIMENSIONS] = {-1};
169 T_IN m_xVal[MAX_DIMENSIONS] = {0};
171 uint8_t m_considDim[MAX_DIMENSIONS] = {0};
173 T_TARGET m_targetDataSel[8 ] = {0};
177 bool m_retValue =
false;
180template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
182: m_limitToBoundaryValues(limitToBoundaryValues)
185 static_assert(MAX_DIMENSIONS == 1 || MAX_DIMENSIONS == 2 || MAX_DIMENSIONS == 3,
"MAX_DIMENSIONS has to be 1, 2 or 3");
188template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
190 uint16_t targetDataSize)
192 if (dimension1Data ==
nullptr || targetData ==
nullptr || targetDataSize != dimension1DataSize)
198 m_dim[0] = dimension1Data;
199 m_dimLen[0] = dimension1DataSize;
200 m_targetData = targetData;
201 m_targetDataSize = targetDataSize;
207template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
209 uint16_t dimension2DataSize,
const T_TARGET targetData[], uint16_t targetDataSize)
211 if (dimension1Data ==
nullptr || dimension2Data ==
nullptr || targetData ==
nullptr || targetDataSize != (dimension1DataSize * dimension2DataSize))
217 m_dim[0] = dimension1Data;
218 m_dim[1] = dimension2Data;
219 m_dimLen[0] = dimension1DataSize;
220 m_dimLen[1] = dimension2DataSize;
221 m_targetData = targetData;
222 m_targetDataSize = targetDataSize;
228template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
230 uint16_t dimension2DataSize,
const T_IN dimension3Data[], uint16_t dimension3DataSize,
231 const T_TARGET targetData[], uint16_t targetDataSize)
233 if (dimension1Data ==
nullptr || dimension2Data ==
nullptr || dimension3Data ==
nullptr || targetData ==
nullptr ||
234 targetDataSize != (dimension1DataSize * dimension2DataSize * dimension3DataSize))
240 m_dim[0] = dimension1Data;
241 m_dim[1] = dimension2Data;
242 m_dim[2] = dimension3Data;
243 m_dimLen[0] = dimension1DataSize;
244 m_dimLen[1] = dimension2DataSize;
245 m_dimLen[2] = dimension3DataSize;
246 m_targetData = targetData;
247 m_targetDataSize = targetDataSize;
253template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
256 if (targetData ==
nullptr || targetDataSize != m_targetDataSize)
262 m_targetData = targetData;
268template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
275 for (uint8_t i = 0; i < MAX_DIMENSIONS; i++)
277 m_dimReduction[i] =
false;
285 m_consideredDimCtr = 0;
286 calculateNeighboringPoints();
289 switch (m_consideredDimCtr)
292 m_yVal = m_targetDataSel[0];
295 interpolateInOneDimension();
298 interpolateInTwoDimensions();
301 interpolateInThreeDimensions();
312template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
315 T_STORAGE nB = 0, nS = 0;
316 uint16_t iS = 1, iB = 1;
318 for (
int i = 0; i <= m_considDim[0]; i++)
323 m_partition += (m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]]);
324 nB += (m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_xVal[m_considDim[0]]);
325 nS += (m_xVal[m_considDim[0]] - m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]]);
326 m_yVal = (m_targetDataSel[iS - 1] * nB + m_targetDataSel[iB - 1] * nS) / m_partition;
329template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
330void LinearInterpolator<MAX_DIMENSIONS, T_IN, T_TARGET, T_STORAGE>::interpolateInTwoDimensions()
332 uint16_t iSS = 1, iBS = 1, iSB = 1, iBB = 1;
333 T_STORAGE nSS, nBS, nSB, nBB;
335 for (
int i = 0; i <= m_considDim[0]; i++)
340 for (
int i = 0; i <= m_considDim[1]; i++)
346 m_partition = (m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]]) *
347 (m_dim[m_considDim[1]][m_iBVec[m_considDim[1]]] - m_dim[m_considDim[1]][m_iSVec[m_considDim[1]]]);
349 nSS = (m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) * (m_dim[m_considDim[1]][m_iSVec[m_considDim[1]]] - m_xVal[m_considDim[1]]);
350 nBS = (m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) * (m_dim[m_considDim[1]][m_iSVec[m_considDim[1]]] - m_xVal[m_considDim[1]]);
351 nSB = (m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) * (m_dim[m_considDim[1]][m_iBVec[m_considDim[1]]] - m_xVal[m_considDim[1]]);
352 nBB = (m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) * (m_dim[m_considDim[1]][m_iBVec[m_considDim[1]]] - m_xVal[m_considDim[1]]);
353 m_yVal = (abs(nSS) * m_targetDataSel[iBB - 1] + abs(nBS) * m_targetDataSel[iSB - 1] + abs(nSB) * m_targetDataSel[iBS - 1] +
354 abs(nBB) * m_targetDataSel[iSS - 1]) /
358template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
359void LinearInterpolator<MAX_DIMENSIONS, T_IN, T_TARGET, T_STORAGE>::interpolateInThreeDimensions()
362 uint16_t iSSS = 1, iBSS = 2, iSBS = 3, iBBS = 4, iSSB = 5, iBSB = 6, iSBB = 7, iBBB = 8;
363 T_STORAGE nSSS, nBSS, nSBS, nBBS, nSSB, nBSB, nSBB, nBBB;
365 m_partition = (m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]]) *
366 (m_dim[m_considDim[1]][m_iBVec[m_considDim[1]]] - m_dim[m_considDim[1]][m_iSVec[m_considDim[1]]]) *
367 (m_dim[m_considDim[2]][m_iBVec[m_considDim[2]]] - m_dim[m_considDim[2]][m_iSVec[m_considDim[2]]]);
369 nSSS = abs((m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) *
370 (m_dim[m_considDim[1]][m_iSVec[m_considDim[1]]] - m_xVal[m_considDim[1]]) *
371 (m_dim[m_considDim[2]][m_iSVec[m_considDim[2]]] - m_xVal[m_considDim[2]]));
372 nBSS = abs((m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) *
373 (m_dim[m_considDim[1]][m_iSVec[m_considDim[1]]] - m_xVal[m_considDim[1]]) *
374 (m_dim[m_considDim[2]][m_iSVec[m_considDim[2]]] - m_xVal[m_considDim[2]]));
375 nSBS = abs((m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) *
376 (m_dim[m_considDim[1]][m_iBVec[m_considDim[1]]] - m_xVal[m_considDim[1]]) *
377 (m_dim[m_considDim[2]][m_iSVec[m_considDim[2]]] - m_xVal[m_considDim[2]]));
378 nBBS = abs((m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) *
379 (m_dim[m_considDim[1]][m_iBVec[m_considDim[1]]] - m_xVal[m_considDim[1]]) *
380 (m_dim[m_considDim[2]][m_iSVec[m_considDim[2]]] - m_xVal[m_considDim[2]]));
381 nSSB = abs((m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) *
382 (m_dim[m_considDim[1]][m_iSVec[m_considDim[1]]] - m_xVal[m_considDim[1]]) *
383 (m_dim[m_considDim[2]][m_iBVec[m_considDim[2]]] - m_xVal[m_considDim[2]]));
384 nBSB = abs((m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) *
385 (m_dim[m_considDim[1]][m_iSVec[m_considDim[1]]] - m_xVal[m_considDim[1]]) *
386 (m_dim[m_considDim[2]][m_iBVec[m_considDim[2]]] - m_xVal[m_considDim[2]]));
387 nSBB = abs((m_dim[m_considDim[0]][m_iSVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) *
388 (m_dim[m_considDim[1]][m_iBVec[m_considDim[1]]] - m_xVal[m_considDim[1]]) *
389 (m_dim[m_considDim[2]][m_iBVec[m_considDim[2]]] - m_xVal[m_considDim[2]]));
390 nBBB = abs((m_dim[m_considDim[0]][m_iBVec[m_considDim[0]]] - m_xVal[m_considDim[0]]) *
391 (m_dim[m_considDim[1]][m_iBVec[m_considDim[1]]] - m_xVal[m_considDim[1]]) *
392 (m_dim[m_considDim[2]][m_iBVec[m_considDim[2]]] - m_xVal[m_considDim[2]]));
394 m_yVal = (nSSS * m_targetDataSel[iBBB - 1] + nBSS * m_targetDataSel[iSBB - 1] + nSBS * m_targetDataSel[iBSB - 1] + nBBS * m_targetDataSel[iSSB - 1] +
395 nSSB * m_targetDataSel[iBBS - 1] + nBSB * m_targetDataSel[iSBS - 1] + nSBB * m_targetDataSel[iBSS - 1] + nBBB * m_targetDataSel[iSSS - 1]) /
399template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
400void LinearInterpolator<MAX_DIMENSIONS, T_IN, T_TARGET, T_STORAGE>::calculateNeighboringPoints()
405 switch (MAX_DIMENSIONS)
408 m_targetDataSel[0] = m_targetData[m_iSVec[0]];
409 m_targetDataSel[1] = m_targetData[m_iBVec[0]];
412 m_targetDataSel[0] = m_targetData[m_iSVec[1] + m_dimLen[1] * m_iSVec[0]];
413 m_targetDataSel[1] = m_targetData[m_iSVec[1] + m_dimLen[1] * m_iBVec[0]];
414 m_targetDataSel[2] = m_targetData[m_iBVec[1] + m_dimLen[1] * m_iSVec[0]];
415 m_targetDataSel[3] = m_targetData[m_iBVec[1] + m_dimLen[1] * m_iBVec[0]];
418 m_targetDataSel[0] = m_targetData[m_iSVec[2] + m_dimLen[2] * m_iSVec[1] + m_dimLen[1] * m_dimLen[2] * m_iSVec[0]];
419 m_targetDataSel[1] = m_targetData[m_iSVec[2] + m_dimLen[2] * m_iSVec[1] + m_dimLen[1] * m_dimLen[2] * m_iBVec[0]];
420 m_targetDataSel[2] = m_targetData[m_iSVec[2] + m_dimLen[2] * m_iBVec[1] + m_dimLen[1] * m_dimLen[2] * m_iSVec[0]];
421 m_targetDataSel[3] = m_targetData[m_iSVec[2] + m_dimLen[2] * m_iBVec[1] + m_dimLen[1] * m_dimLen[2] * m_iBVec[0]];
422 m_targetDataSel[4] = m_targetData[m_iBVec[2] + m_dimLen[2] * m_iSVec[1] + m_dimLen[1] * m_dimLen[2] * m_iSVec[0]];
423 m_targetDataSel[5] = m_targetData[m_iBVec[2] + m_dimLen[2] * m_iSVec[1] + m_dimLen[1] * m_dimLen[2] * m_iBVec[0]];
424 m_targetDataSel[6] = m_targetData[m_iBVec[2] + m_dimLen[2] * m_iBVec[1] + m_dimLen[1] * m_dimLen[2] * m_iSVec[0]];
425 m_targetDataSel[7] = m_targetData[m_iBVec[2] + m_dimLen[2] * m_iBVec[1] + m_dimLen[1] * m_dimLen[2] * m_iBVec[0]];
434template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
435void LinearInterpolator<MAX_DIMENSIONS, T_IN, T_TARGET, T_STORAGE>::getPointIndecies()
437 for (uint8_t i = 0; i < MAX_DIMENSIONS; i++)
439 if (m_limitToBoundaryValues)
441 if (m_xVal[i] > m_dim[i][m_dimLen[i] - 1])
443 m_xVal[i] = m_dim[i][m_dimLen[i] - 1];
445 else if (m_xVal[i] < m_dim[i][0])
447 m_xVal[i] = m_dim[i][0];
452 while ((m_dim[i][m_iBVec[i]] < m_xVal[i]) && (m_iBVec[i] < m_dimLen[i]))
458 if (m_dim[i][m_iBVec[i]] == m_xVal[i])
460 m_iSVec[i] = m_iBVec[i];
461 m_dimReduction[i] =
true;
465 m_iSVec[i] = m_iBVec[i] - 1;
466 m_considDim[m_consideredDimCtr] = i;
467 m_consideredDimCtr++;
470 checkDimensionBoundaries();
473template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
474void LinearInterpolator<MAX_DIMENSIONS, T_IN, T_TARGET, T_STORAGE>::checkDimensionBoundaries()
476 for (uint8_t i = 0; i < MAX_DIMENSIONS; i++)
478 if ((m_iSVec[i] < 0) || (m_iBVec[i] >= m_dimLen[i]))
485template <u
int8_t MAX_DIMENSIONS,
typename T_IN,
typename T_TARGET,
typename T_STORAGE>
486T_STORAGE LinearInterpolator<MAX_DIMENSIONS, T_IN, T_TARGET, T_STORAGE>::abs(T_STORAGE input)
Class for calculating the linear interpolation. It interpolates till 3-dimensional data.
bool interpolate(T_TARGET &y, T_IN x1=0, T_IN x2=0, T_IN x3=0)
Calculates the interpolation of a given data point.
virtual ~LinearInterpolator()=default
LinearInterpolator(bool limitToBoundaryValues=true)
bool setTargetDataInputDimension(const T_TARGET targetData[], uint16_t targetDataSize)
It updates/changes the m_targetDataSource array.
bool init(const T_IN dimension1Data[], uint16_t dimension1DataSize, const T_TARGET targetData[], uint16_t targetDataSize)
Initializes the class members with 1 dimensional data points.