143 lines
3.4 KiB
C++
143 lines
3.4 KiB
C++
/*
|
|
* rt_look.cpp
|
|
*
|
|
* Academic License - for use in teaching, academic research, and meeting
|
|
* course requirements at degree granting institutions only. Not for
|
|
* government, commercial, or other organizational use.
|
|
*
|
|
* Code generation for model "VFControl".
|
|
*
|
|
* Model version : 1.1
|
|
* Simulink Coder version : 24.1 (R2024a) 19-Nov-2023
|
|
* C++ source code generated on : Wed Oct 16 10:45:53 2024
|
|
*/
|
|
|
|
#include "rtwtypes.h"
|
|
#include "rt_look.h"
|
|
#ifdef __cplusplus
|
|
|
|
extern "C"
|
|
{
|
|
|
|
#endif
|
|
|
|
/*
|
|
* Routine to get the index of the input from a table using binary or
|
|
* interpolation search.
|
|
*
|
|
* Inputs:
|
|
* *x : Pointer to table, x[0] ....x[xlen-1]
|
|
* xlen : Number of values in xtable
|
|
* u : input value to look up
|
|
*
|
|
* Output:
|
|
* idx : the index into the table such that:
|
|
* if u is negative
|
|
* x[idx] <= u < x[idx+1]
|
|
* else
|
|
* x[idx] < u <= x[idx+1]
|
|
*
|
|
* Interpolation Search: If the table contains a large number of nearly
|
|
* uniformly spaced entries, i.e., x[n] vs n is linear then the index
|
|
* corresponding to the input can be found in one shot using the linear
|
|
* interpolation formula. Therefore if you have a look-up table block with
|
|
* many data points, using interpolation search might speed up the code.
|
|
* Compile the generated code with the following flag:
|
|
*
|
|
* make_rtw OPTS=-DDOINTERPSEARCH
|
|
*
|
|
* to enable interpolation search.
|
|
*/
|
|
int_T rt_GetLookupIndex(const real_T *x, int_T xlen, real_T u)
|
|
{
|
|
int_T idx = 0;
|
|
int_T bottom = 0;
|
|
int_T top = xlen-1;
|
|
int_T retValue = 0;
|
|
boolean_T returnStatus = 0U;
|
|
|
|
#ifdef DOINTERPSEARCH
|
|
|
|
real_T offset = 0;
|
|
|
|
#endif
|
|
|
|
/*
|
|
* Deal with the extreme cases first:
|
|
* if u <= x[bottom] then return idx = bottom
|
|
* if u >= x[top] then return idx = top-1
|
|
*/
|
|
if (u <= x[bottom]) {
|
|
retValue = bottom;
|
|
returnStatus = 1U;
|
|
} else if (u >= x[top]) {
|
|
retValue = top-1;
|
|
returnStatus = 1U;
|
|
} else {
|
|
/* else required to ensure safe programming, even *
|
|
* if it's expected that it will never be reached */
|
|
}
|
|
|
|
if (returnStatus == 0U) {
|
|
if (u < 0) {
|
|
/* For negative input find index such that: x[idx] <= u < x[idx+1] */
|
|
for (;;) {
|
|
|
|
#ifdef DOINTERPSEARCH
|
|
|
|
offset = (u-x[bottom])/(x[top]-x[bottom]);
|
|
idx = bottom + (int_T)((top-bottom)*(offset-DBL_EPSILON));
|
|
|
|
#else
|
|
|
|
idx = (bottom + top)/2;
|
|
|
|
#endif
|
|
|
|
if (u < x[idx]) {
|
|
top = idx - 1;
|
|
} else if (u >= x[idx+1]) {
|
|
bottom = idx + 1;
|
|
} else {
|
|
/* we have x[idx] <= u < x[idx+1], return idx */
|
|
retValue = idx;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
/* For non-negative input find index such that: x[idx] < u <= x[idx+1] */
|
|
for (;;) {
|
|
|
|
#ifdef DOINTERPSEARCH
|
|
|
|
offset = (u-x[bottom])/(x[top]-x[bottom]);
|
|
idx = bottom + (int_T)((top-bottom)*(offset-DBL_EPSILON));
|
|
|
|
#else
|
|
|
|
idx = (bottom + top)/2;
|
|
|
|
#endif
|
|
|
|
if (u <= x[idx]) {
|
|
top = idx - 1;
|
|
} else if (u > x[idx+1]) {
|
|
bottom = idx + 1;
|
|
} else {
|
|
/* we have x[idx] < u <= x[idx+1], return idx */
|
|
retValue = idx;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return retValue;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
|
|
} /* extern "C" */
|
|
|
|
#endif
|