%implements "Lookup_n-D" "C"
%function BlockInstanceSetup(block, system) void
%endfunction
%function FcnSplineSecondDerivInitInSharedUtility(block) void
%assign ioTypeUn = LibBlockOutputSignalDataTypeId(0)
%assign ioTypeId = LibGetDataTypeIdAliasedThruToFromId(ioTypeUn)
%if ioTypeId != tSS_DOUBLE && ioTypeId != tSS_SINGLE
%exit "Spline interpolation only supports floating point data types."
%endif
%assign dTypeIdx = (ioTypeId == tSS_DOUBLE) ? 0 : 1
%assign DdType = [ "d", "f" ]
%assign DdSuffix = ["", "F"]
%assign DdTypeName = ["real_T", "real32_T"]
%assign dType = DdType[dTypeIdx]
%assign dSuffix = DdSuffix[dTypeIdx]
%assign dTypeName = DdTypeName[dTypeIdx]
%assign derivName = "rt_Spline2Deriv%<dType>"
%assign derivName = SLibRegisterSharedUtility(block, derivName)
%if !(ISFIELD(FixPtUtils, derivName))
%<LibPushEmptyStackSharedUtils()>
%assign tmpRet = SETFIELD(FixPtUtils, derivName,1)
%openfile derivFcnBody
%assign tmpfcnName = "%<derivName>"
%assign fcnReturns = "void"
%assign fcnParams = ["const %<dTypeName> *x, ", "const %<dTypeName> *y, ",...
"uint32_T n, ", "%<dTypeName> *u, ", "%<dTypeName> *y2"]
%assign derivDecRoot = "%<fcnReturns> %<tmpfcnName>(%" + ...
"%" + "%" + ...
"%" + "%)"
%openfile derivPrototype
%<derivDecRoot>;
%closefile derivPrototype
{
%<dTypeName> p, qn, sig, un;
uint32_T n1, i, k;
n1 = n - 1U;
y2[0U] = 0.0%<dSuffix>;
u[0U] = 0.0%<dSuffix>;
for (i = 1U; i < n1; i++)
{
%<dTypeName> dxm1 = x[i] - x[i - 1U];
%<dTypeName> dxp1 = x[i + 1U] - x[i];
%<dTypeName> dxpm = dxp1 + dxm1;
sig = dxm1 / dxpm;
p = (sig * y2[i - 1U]) + 2.0%<dSuffix>;
y2[i] = (sig - 1.0%<dSuffix>) / p;
u[i] = ((y[i + 1U] - y[i]) / dxp1) - ((y[i] - y[i - 1U]) / dxm1);
u[i] = (((6.0%<dSuffix> * u[i]) / dxpm) - (sig * u[i - 1U])) / p;
}
qn = 0.0%<dSuffix>;
un = 0.0%<dSuffix>;
y2[n1] = (un - (qn * u[n1 - 1U])) / ((qn * y2[n1 - 1U]) + 1.0%<dSuffix>);
for (k = n1; k > 0U; k--)
{
y2[k-1U] = (y2[k-1U] * y2[k]) + u[k-1U];
}
return;
}
%closefile derivFcnBody
%openfile derivDef
%openfile fcnAbstract
Second derivative initialization function for spline
for last dimension.
%closefile fcnAbstract
%createrecord derivFcnRec {Name tmpfcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "utility"; GeneratedBy "lookup_nd.tlc"}
%<SLibDumpFunctionBanner(derivFcnRec)>
%undef derivFcnRec
%<derivDecRoot>
%<derivFcnBody>
%closefile derivDef
%<FcnTrackHeaderFileUsage("rtsplntypes.h", TLC_FALSE, TLC_FALSE)>
%openfile rtlookIncl
#include "rtsplntypes.h"
%closefile rtlookIncl
%<SLibDumpUtilsSourceCodeWithPrototypeIncludesAndCached(derivName, derivPrototype, derivDef, rtlookIncl)>/
%assign derivStackBuf = LibPopStackSharedUtilsIncludes()
%endif
%<FcnTrackSharedUtilHeaderFileUsage(derivName + ".h", TLC_FALSE)>
%return derivName
%endfunction
%function FcnGenerateSplineInSharedUtility(block) void
%assign ioTypeUn = LibBlockOutputSignalDataTypeId(0)
%assign ioTypeId = LibGetDataTypeIdAliasedThruToFromId(ioTypeUn)
%assign dTypeRec = DataTypes.DataType[ioTypeId]
%if ioTypeId != tSS_DOUBLE && ioTypeId != tSS_SINGLE
%exit "Spline interpolation only supports floating point data types."
%endif
%assign interpIdx = ParamSettings.interpMethod - 1
%assert (interpIdx == 2)
%assign searchIdx = ParamSettings.searchMode - 1
%assign extrapIdx = ParamSettings.extrapMethod - 1
%assert (searchIdx != 0 || ParamSettings.cacheBpFlag == 0)
%assign cacheIdx = (searchIdx == 0) ? 0 : ParamSettings.cacheBpFlag
%assign dTypeIdx = (ioTypeId == tSS_DOUBLE) ? 0 : 1
%assign Dsearch = [ "Evn", "Lin", "Bin" ]
%assign DsearchDesc = ["Evenly-spaced breakpoints", ...
"Linear breakpoint search", ...
"Binary breakpoint search"]
%assign Dextrap = [ "C", "X", "S" ]
%assign DextrapDesc = ["Clipping", ...
"Linear extrapolation", ...
"Spline extrapolation"]
%assign DcacheBp = [ "Z", "S" ]
%assign DcacheDesc = ["Index search starts at the same place each time", ...
"Uses previous index search result"]
%assign DdType = [ "d", "f" ]
%assign DdSuffix = ["", "F"]
%assign DdTypeName = ["real_T", "real32_T"]
%assign interp = "Spl"
%assign interpDesc = "Spline interpolation"
%assign search = Dsearch[searchIdx]
%assign searchDesc = DsearchDesc[searchIdx]
%assign extrap = Dextrap[extrapIdx]
%assign extrapDesc = DextrapDesc[extrapIdx]
%assign cache = DcacheBp[cacheIdx]
%assign cacheDesc = DcacheDesc[cacheIdx]
%assign dType = DdType[dTypeIdx]
%assign dSuffix = DdSuffix[dTypeIdx]
%assign dTypeName = DdTypeName[dTypeIdx]
%assign numDims = "N"
%if ParamSettings.vectorInputFlag == 0
%assign numDims_ev = NumDataInputPorts
%else
%assign numDims_ev = LibBlockInputSignalWidth(0)
%endif
%if ParamSettings.preCalcSecondDerivFirstDimCoeffs
%assign calcCoeff = ""
%else
%assign calcCoeff = "c"
%endif
%if (search == "Evn")
%assign fcnName = "look_SplN" + search + extrap + cache + calcCoeff + dType + "%<numDims_ev>" + "D"
%else
%assign fcnName = "look_SplN" + search + extrap + cache + calcCoeff + dType
%endif
%assign fcnName = SLibRegisterSharedUtility(block, fcnName)
%assign interpName = "intrp_NSpl" + calcCoeff + dType
%assign interpName = SLibRegisterSharedUtility(block, interpName)
%if !(ISFIELD(FixPtUtils, fcnName))
%<LibPushEmptyStackSharedUtils()>
%assign tmpRet = SETFIELD(FixPtUtils, fcnName,1)
%assign fcnParams = ["uint32_T numDims, ", "const %<dTypeName>* u, ", "const rt_LUTSplineWork * const SWork"]
%assign fcnReturns = dTypeName
%assign fcnDecRoot = ...
"%<fcnReturns> %<fcnName>(%" + ...
fcnParams[1] + fcnParams[2] +")"
%openfile fcnPrototype
%<fcnDecRoot>;
%closefile fcnPrototype
%openfile fcnBody
rt_LUTnWork * const TWork_look = SWork->m_TWork;
%assign idxRef = ""
%assign idxRef = (cache == "S") ? "bpIdx[k]" : "dummy"
%if (search == "Evn")
%assign idxRef = ""
%endif
%assign castStr = "(%<dTypeName>*) TWork_look->m_bpLambda"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
%<dTypeName>* const fraction = %<castStr>;
uint32_T* const bpIdx = TWork_look->m_bpIndex;
const uint32_T* const maxIndex = TWork_look->m_maxIndex;
%assign checkRangeInCode = ParamSettings.checkRangeInCode
%if !SLibIsValidCoderContext()
%error "Code generation for this block is not supported, if the TLC command is invoked offline"
%endif
%assign rtwCtx = ::CompiledModel.RTWContext
%if (search == "Evn")
const %<dTypeName>* bpData = 0;
%assign dims = ParamSettings.tableDims
%foreach k = numDims_ev
%assign maxId = dims[k]-1
bpData = ((const %<dTypeName> * * )TWork_look->m_bpDataSet)[%<k>];
%assign vec = FEVAL("rtwprivate", "rtwcgtlc", "PreLookup", rtwCtx, ...
dTypeRec, "u[%<k>]", "bpData", idxRef, "bpIdx[%<k>]", ...
"fraction[%<k>]", search, interp, extrap, cache, ...
"maxIndex[%<k>]", maxId, checkRangeInCode)
%/
%assign headers = vec[3]
%foreach idx = SIZE(headers, 1)
%<FcnTrackHeaderFileUsage(headers[idx], TLC_FALSE, TLC_FALSE)>
%endforeach
%endforeach
%else
uint32_T k;
for(k = 0U; k < numDims; k++)
{
const %<dTypeName>* const bpData = ((const %<dTypeName> * const *)TWork_look->m_bpDataSet)[k];
%assign vec = FEVAL("rtwprivate", "rtwcgtlc", "PreLookup", rtwCtx, ...
dTypeRec, "u[k]", "bpData", idxRef, "bpIdx[k]", "fraction[k]", ...
search, interp, extrap, cache, "maxIndex[k]", checkRangeInCode)
%/
}
%assign headers = vec[3]
%foreach idx = SIZE(headers, 1)
%<FcnTrackHeaderFileUsage(headers[idx], TLC_FALSE, TLC_FALSE)>
%endforeach
%endif
%assign eIdx = CAST("Unsigned", extrapIdx+1)
%<FcnTrackSharedUtilHeaderFileUsage(interpName + ".h", TLC_FALSE)>
return(%<interpName>(numDims, SWork, %<eIdx>));
%closefile fcnBody
%openfile fcnDef
%assign fcnAbstract = "n-D Spline interpolation function"
%createrecord fcnRec {Name fcnName; Returns fcnReturns; Params fcnParams; Abstract fcnAbstract; ...
Category "utility"; GeneratedBy "lookup_nd.tlc"}
%<SLibDumpFunctionBanner(fcnRec)>
%undef fcnRec
%<fcnDecRoot>
{
/*
* n-D column-major table lookup operating on %<dTypeName> with:
* - %<interpDesc>
* - %<extrapDesc>
* - %<searchDesc>
* - %<cacheDesc>
*/
%<fcnBody>
}
%closefile fcnDef
%<FcnTrackHeaderFileUsage("rtsplntypes.h", TLC_FALSE, TLC_FALSE)>
%openfile rtlookIncl
#include "rtsplntypes.h"
%closefile rtlookIncl
%<SLibDumpUtilsSourceCodeWithPrototypeIncludesAndCached(fcnName, fcnPrototype, fcnDef, rtlookIncl)>/
%assign lookStackBuf = LibPopStackSharedUtilsIncludes()
%endif
%if !(ISFIELD(FixPtUtils, interpName))
%<LibPushEmptyStackSharedUtils()>
%assign tmpRet = SETFIELD(FixPtUtils, interpName,1)
%assign tmpfcnName = "%<interpName>"
%assign fcnParams = ["uint32_T numDims, ", ...
"const rt_LUTSplineWork * const splWork, ", "uint32_T extrapMethod"]
%createrecord interpFcnRec {Name tmpfcnName; Returns dTypeName; Params fcnParams}
%assign interpDecRoot = ...
"%<dTypeName> %<tmpfcnName>(%" + ...
"%" + ...
"%)"
%openfile interpPrototype
%<interpDecRoot>;
%closefile interpPrototype
%openfile interpBody
uint32_T il;
uint32_T iu, k, i;
%if (ParamSettings.hasPrevBp0AndTableData) && (::CompiledModel.ConfigSet.EnableMemcpy == 0)
uint32_T index;
%endif
%<dTypeName> h, s, p, smsq, pmsq;
/* intermediate results work areas "this" and "next" */
%assign castStr = "(const rt_LUTnWork *)splWork->m_TWork"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
const rt_LUTnWork *TWork_interp = %<castStr>;
%assign castStr = "(%<dTypeName> *) TWork_interp->m_bpLambda"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
const %<dTypeName> *fraction = %<castStr>;
%assign castStr = "(%<dTypeName> *) TWork_interp->m_tableData"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
const %<dTypeName> *yp = %<castStr>;
%assign castStr = "(%<dTypeName> *) splWork->m_yyA"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
%<dTypeName> *yyA = %<castStr>;
%assign castStr = "(%<dTypeName> *) splWork->m_yyB"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
%<dTypeName> *yyB = %<castStr>;
%assign castStr = "(%<dTypeName> *) splWork->m_yy2"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
%<dTypeName> *yy2 = %<castStr>;
%assign castStr = "(%<dTypeName> *) splWork->m_up"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
%<dTypeName> *up = %<castStr>;
%assign castStr = "(%<dTypeName> *) splWork->m_y2"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
%<dTypeName> *y2 = %<castStr>;
%if (ParamSettings.hasReCalcFlag)
uint8_T* reCalc = splWork->m_reCalc;
%endif
%if (ParamSettings.hasPrevBp0AndTableData)
%assign castStr = "(%<dTypeName> *) splWork->m_preBp0AndTable"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
%<dTypeName> *dp = %<castStr>;
%endif
const %<dTypeName> **bpDataSet = (const %<dTypeName> **) TWork_interp->m_bpDataSet;
const %<dTypeName> *xp = bpDataSet[0U];
%<dTypeName> *yy = yyA;
uint32_T bufBank = 0U;
uint32_T len = TWork_interp->m_maxIndex[0U] + 1U;
%if !(ParamSettings.preCalcSecondDerivFirstDimCoeffs)
%if (ParamSettings.hasPrevBp0AndTableData)
/* compare bp0 and table to see whether they get changed */
{
%if ::CompiledModel.ConfigSet.EnableMemcpy
/* compare the bp0 data */
if(%<LibGenMemFcnCall("memcmp", "dp", "xp", "len * sizeof(%<dTypeName>)")> != 0)
{
*reCalc = 1;
(void) %<LibGenMemFcnCall("memcpy", "dp", "xp", "len * sizeof(%<dTypeName>)")>;
}
/* compare the table data */
dp = &(dp[len]);
if(%<LibGenMemFcnCall("memcmp", "dp", "yp", "len * splWork->m_numYWorkElts[0U] * sizeof(%<dTypeName>)")> != 0)
{
*reCalc = 1;
(void) %<LibGenMemFcnCall("memcpy", "dp", "yp", "len * splWork->m_numYWorkElts[0U] * sizeof(%<dTypeName>)")>;
}
%else
/* compare the bp0 data */
for (i = 0U; i < len; i++)
{
if(dp[i] != xp[i])
{
*reCalc = 1;
dp[i] = xp[i];
}
}
dp = &(dp[len]);
/* compare the table data */
index = 0;
for (i = 0U; i < splWork->m_numYWorkElts[0U]; i++)
{
for (k = 0U; k < len; k++)
{
if (dp[index] != yp[index])
{
*reCalc = 1;
dp[index] = yp[index];
}
++index;
}
}
%endif
}
%endif
%if (ParamSettings.hasReCalcFlag)
if (*reCalc == 1) {
%endif
/* If table and bps are tunable calculate 1st dim 2nd deriv */
/* Generate first dimension's second derivatives */
for (i = 0U; i < splWork->m_numYWorkElts[0U]; i++)
{
%assign derivName = FcnSplineSecondDerivInitInSharedUtility(block)
%<derivName>(xp, yp, len, up, y2);
yp = &yp[len];
y2 = &y2[len];
}
/* Set pointers back to beginning */
yp = (const %<dTypeName> *) TWork_interp->m_tableData;
y2 = (%<dTypeName> *) splWork->m_y2;
%if (ParamSettings.hasReCalcFlag)
}
*reCalc = 0;
%endif
%endif
/* Generate at-point splines in each dimension */
for( k = 0U; k < numDims; k++ )
{
/* this dimension's input setup */
xp = bpDataSet[k];
len = TWork_interp->m_maxIndex[k] + 1U;
il = TWork_interp->m_bpIndex[k];
iu = il + 1U;
h = xp[iu] - xp[il];
p = fraction[k];
s = 1.0%<dSuffix> - p;
pmsq = p * ((p*p) - 1.0%<dSuffix>);
smsq = s * ((s*s) - 1.0%<dSuffix>);
/*
* Calculate spline curves for input in this
* dimension at each value of the higher
* other dimensions/' points in the table.
*/
if ( (p > 1.0%<dSuffix>) && (extrapMethod == 2U) )
{
%<dTypeName> slope;
for (i = 0U; i < splWork->m_numYWorkElts[k]; i++)
{
slope = (yp[iu] - yp[il]) + ((y2[il]*h*h)*(1.0%<dSuffix>/6.0%<dSuffix>));
yy[i] = yp[iu] + (slope * (p-1.0%<dSuffix>));
yp = &yp[len];
y2 = &y2[len];
}
}
else if ( (p < 0.0%<dSuffix>) && (extrapMethod == 2U) )
{
%<dTypeName> slope;
for (i = 0U; i < splWork->m_numYWorkElts[k]; i++)
{
slope = (yp[iu] - yp[il]) - ((y2[iu]*h*h)*(1.0%<dSuffix>/6.0%<dSuffix>));
yy[i] = yp[il] + (slope * p);
yp = &yp[len];
y2 = &y2[len];
}
}
else
{
for (i = 0U; i < splWork->m_numYWorkElts[k]; i++)
{
yy[i] = yp[il] + p * (yp[iu] - yp[il]) +
((smsq * y2[il] + pmsq * y2[iu])*h*h)*(1.0%<dSuffix>/6.0%<dSuffix>);
yp = &yp[len];
y2 = &y2[len];
}
}
/* set pointers to new result and calculate second derivatives */
yp = yy;
y2 = yy2;
if ( splWork->m_numYWorkElts[k+1U] > 0U )
{
uint32_T nextLen = TWork_interp->m_maxIndex[k+1U] + 1U;
const %<dTypeName> *nextXp = bpDataSet[k+1U];
for (i = 0U; i < splWork->m_numYWorkElts[k+1U]; i++)
{
%assign derivName = FcnSplineSecondDerivInitInSharedUtility(block)
%<derivName>(nextXp, yp, nextLen, up, y2);
yp = &yp[nextLen];
y2 = &y2[nextLen];
}
}
/*
* Set work vectors yp, y2 and yy for next iteration;
* the yy just calculated becomes the yp in the
* next iteration, y2 was just calculated for these
* new points and the yy buffer is swapped to the space
* for storing the next iteration/'s results.
*/
yp = yy;
y2 = yy2;
/*
* Swap buffers for next dimension and
* toggle bufBank for next iteration.
*/
if (bufBank == 0U)
{
yy = yyA;
bufBank = 1U;
}
else
{
yy = yyB;
bufBank = 0U;
}
}
return( yp[0U] );
%closefile interpBody
%openfile interpDef
%assign fcnAbstract = "n-D natural spline calculation function"
%addtorecord interpFcnRec Abstract fcnAbstract Category "utility" GeneratedBy "lookup_nd.tlc"
%<SLibDumpFunctionBanner(interpFcnRec)>
%undef interpFcnRec
%<interpDecRoot>
{
%<interpBody>
}
%closefile interpDef
%<FcnTrackHeaderFileUsage("rtsplntypes.h", TLC_FALSE, TLC_FALSE)>
%openfile rtlookIncl
#include "rtsplntypes.h"
%closefile rtlookIncl
%<SLibDumpUtilsSourceCodeWithPrototypeIncludesAndCached(interpName, interpPrototype, interpDef, rtlookIncl)>/
%assign interpStackBuf = LibPopStackSharedUtilsIncludes()
%endif
%assign tmpfcnName = FcnSplineSecondDerivInitInSharedUtility(block)
%return fcnName
%endfunction
%function Start(block, system) Output
%assign NUM_DIMS_FOR_TWORK = 6
%assign INTERP_FLAT = 1
%assign INTERP_LINEAR = 2
%assign INTERP_SPLINE = 3
%assign interpMethod = ParamSettings.interpMethod
%assign idxTypeId = tSS_UINT32
%assign idxType = LibGetDataTypeNameFromId(idxTypeId)
%assign ioTypeUn = LibBlockOutputSignalDataTypeId(0)
%assign ioTypeId = LibGetDataTypeIdAliasedThruToFromId(ioTypeUn)
%if ioTypeId != tSS_DOUBLE && ioTypeId != tSS_SINGLE
%exit "Spline interpolation only supports floating point data types."
%endif
%assign dTypeIdx = (ioTypeId == tSS_DOUBLE) ? 0 : 1
%assign DdTypeName = ["real_T", "real32_T"]
%assign dTypeName = DdTypeName[dTypeIdx]
%assign DdType = [ "d", "f" ]
%assign dType = DdType[dTypeIdx]
%if ParamSettings.vectorInputFlag == 0
%assign numDims = NumDataInputPorts
%else
%assign numDims = LibBlockInputSignalWidth(0)
%endif
%assign dims = ParamSettings.tableDims
%if ParamSettings.vectorInputFlag == 0
%assign numEl = NumDataInputPorts
%else
%assign numEl = LibBlockInputSignalWidth(0)
%endif
%if (interpMethod == INTERP_SPLINE )
{
rt_LUTnWork *TWork_start = (rt_LUTnWork *) %<LibBlockDWorkAddr(TWork,"","",0)>;
%assign castStr = "(void **) %<LibBlockDWorkAddr(m_bpDataSet,"","",0)>"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
void **bpDataSet = %<castStr>;
%assign castStr = "(const %<idxType> *) %<LibBlockParameterBaseAddr(dimSizes)>"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
TWork_start->m_dimSizes = %<castStr>;
TWork_start->m_tableData = (void *) %<LibBlockParameterBaseAddr(Table)>;
TWork_start->m_bpDataSet = bpDataSet;
TWork_start->m_bpIndex = %<LibBlockDWorkAddr(m_bpIndex,"","",0)>;
TWork_start->m_bpLambda = %<LibBlockDWorkAddr(m_bpLambda,"","",0)>;
%assign castStr = "(const %<idxType> *) %<LibBlockParameterBaseAddr(maxIndex)>"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
TWork_start->m_maxIndex = %<castStr>;
%foreach idx = numDims
%assign lzIdx = FEVAL("sprintf","%d",idx+1)
%assign rtpName = "BreakpointsForDimension%<lzIdx>"
bpDataSet[%<idx>] = (void *) %<LibBlockParameterBaseAddr(GETFIELD(block,rtpName))>;
%endforeach
}
{
%if ((ParamSettings.preCalcSecondDerivFirstDimCoeffs) || (ParamSettings.hasPrevBp0AndTableData))
const %<dTypeName> **bpDataSet;
const %<dTypeName> *xp, *yp;
%if (ParamSettings.preCalcSecondDerivFirstDimCoeffs)
%<dTypeName> *up, *y2;
uint32_T i, len;
%endif
%if (ParamSettings.hasPrevBp0AndTableData)
%if (::CompiledModel.ConfigSet.EnableMemcpy == 0)
uint32_T i, j, index;
%endif
%<dTypeName> *dp;
uint32_T len;
%endif
const rt_LUTnWork *TWork_interp;
%endif
%<FcnTrackHeaderFileUsage("rtsplntypes.h", TLC_FALSE, TLC_FALSE)>
rt_LUTSplineWork *rt_SplWk = (rt_LUTSplineWork*)%<LibBlockDWorkAddr(SWork,"","",0)>;
rt_SplWk->m_TWork = (rt_LUTnWork*)%<LibBlockDWorkAddr(TWork, "", "", 0)>;
rt_SplWk->m_yyA = %<LibBlockDWorkAddr(m_yyA, "", "", 0)>;
rt_SplWk->m_yyB = %<LibBlockDWorkAddr(m_yyB, "", "", 0)>;
rt_SplWk->m_yy2 = %<LibBlockDWorkAddr(m_yy2, "", "", 0)>;
rt_SplWk->m_up = %<LibBlockDWorkAddr(m_up, "", "", 0)>;
rt_SplWk->m_y2 = %<LibBlockDWorkAddr(m_y2, "", "", 0)>;
rt_SplWk->m_numYWorkElts = %<LibBlockParameterBaseAddr(numYWorkElts)>;
%if (ParamSettings.hasReCalcFlag)
rt_SplWk->m_reCalc = %<LibBlockDWorkAddr(reCalcSecDerivFirstDimCoeffs, "", "", 0)>;
%endif
%if (ParamSettings.hasPrevBp0AndTableData)
rt_SplWk->m_preBp0AndTable = %<LibBlockDWorkAddr(prevBp0AndTableData, "", "", 0)>;
%endif
%if (ParamSettings.hasReCalcFlag)
*rt_SplWk->m_reCalc = 1;
%endif
%if (ParamSettings.hasPrevBp0AndTableData)
/* cache table data and first breakpoint data */
%assign castStr = "(const rt_LUTnWork *)rt_SplWk->m_TWork"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
TWork_interp = %<castStr>;
bpDataSet = (const %<dTypeName> **) TWork_interp->m_bpDataSet;
xp = bpDataSet[0U];
len = TWork_interp->m_maxIndex[0U] + 1U;
dp = (%<dTypeName> *) rt_SplWk->m_preBp0AndTable;
yp = (%<dTypeName> *) TWork_interp->m_tableData;
%if ::CompiledModel.ConfigSet.EnableMemcpy
(void) %<LibGenMemFcnCall("memcpy", "dp", "xp", "len * sizeof(%<dTypeName>)")>;
dp = &(dp[len]);
/* save the table data */
(void) %<LibGenMemFcnCall("memcpy", "dp", "yp", "len * rt_SplWk->m_numYWorkElts[0U] * sizeof(%<dTypeName>)")>;
%else
/* save the bp0 data */
for (j = 0U; j < len; j++)
{
dp[j] = xp[j];
}
dp = &(dp[len]);
/* save the table data */
index = 0;
for (i = 0U; i < rt_SplWk->m_numYWorkElts[0U]; i++)
{
for (j = 0U; j < len; j++)
{
dp[index] = yp[index];
}
++index;
}
%endif
%endif
%if ParamSettings.preCalcSecondDerivFirstDimCoeffs
/* If table and bps are not-tunable then precalculate 1st dim 2nd deriv */
%assign castStr = "(const rt_LUTnWork *)rt_SplWk->m_TWork"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
TWork_interp = %<castStr>;
bpDataSet = (const %<dTypeName> **) TWork_interp->m_bpDataSet;
xp = bpDataSet[0U];
%assign castStr = "(%<dTypeName> *) TWork_interp->m_tableData"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
yp = %<castStr>;
len = TWork_interp->m_maxIndex[0U] + 1U;
%assign castStr = "(%<dTypeName> *) rt_SplWk->m_up"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
up = %<castStr>;
%assign castStr = "(%<dTypeName> *) rt_SplWk->m_y2"
%assign castStr = FcnReplaceCCastWithStaticCastForCPP(castStr)
y2 = %<castStr>;
/* Generate first dimension's second derivatives */
for (i = 0U; i < rt_SplWk->m_numYWorkElts[0U]; i++)
{
%assign derivName = FcnSplineSecondDerivInitInSharedUtility(block)
%<derivName>(xp, yp, len, up, y2);
yp = &yp[len];
y2 = &y2[len];
}
%endif
}
%else
%setcommandswitch "-v1"
%exit This function should only be used for splines.
%endif
%endfunction
%function Outputs(block, system) Output
%assign INTERP_FLAT = 1
%assign INTERP_LINEAR = 2
%assign INTERP_SPLINE = 3
%assign BPSEARCH_EVEN = 1
%assign BPSEARCH_LINEAR = 2
%assign BPSEARCH_BINARY = 3
%assign ioType = LibBlockOutputSignalDataTypeName(0,"")
%if ParamSettings.vectorInputFlag == 0
%assign numDims = NumDataInputPorts
%else
%assign numDims = LibBlockInputSignalWidth(0)
%endif
%assign numDimsArg = CAST("Unsigned", numDims)
%assign dims = ParamSettings.tableDims
%assign tabDimsStr = "%<CAST("Number", dims[0])>"
%foreach i = %<SIZE(dims,1)*SIZE(dims,0)-1>
%assign tabDimsStr = tabDimsStr + " x " + "%<CAST("Number", dims[i+1])>"
%endforeach
%assign interpStr = [ "None - Flat Look-Up", "Linear", "Spline" ]
%assign extrapStr = [ "None - Clip", "Linear", "Spline" ]
%assign Dsearch = [ "Evenly Spaced Points", "Linear", "Binary" ]
%assign bpCache = [ "OFF", "ON" ]
%openfile comment
* Table size: %<tabDimsStr>
* Interpolation: %
* Extrapolation: %
* Breakpt Search: %
* Breakpt Cache: %
%closefile comment
%<LibCacheBlockComment(block, comment)>
%assign y = LibBlockOutputSignal(0,"","",0)
%if ParamSettings.interpMethod != INTERP_SPLINE
%setcommandswitch "-v1"
%exit This function should only be used for splines.
%else
%assign splFcnName = FcnGenerateSplineInSharedUtility(block)
%<FcnTrackSharedUtilHeaderFileUsage(splFcnName + ".h", TLC_FALSE)>
%<FcnTrackHeaderFileUsage("rtsplntypes.h", TLC_FALSE, TLC_FALSE)>
%assign xSWork = "(rt_LUTSplineWork*)%<LibBlockDWorkAddr(SWork,"","",0)>"
%if (numDims == 1)
%assign u = LibBlockInputSignalAddr(0,"","",0)
%<y> = %<splFcnName>(%<numDimsArg>, %<u>, %<xSWork>);
%else
%if (ParamSettings.vectorInputFlag == 0)
{
%<ioType> rt_LUTuVect[%<numDims>];
%foreach idx = numDims
rt_LUTuVect[%<idx>] = %<LibBlockInputSignal(idx,"","",0)>;
%endforeach
%<y> = %<splFcnName>(%<numDimsArg>, rt_LUTuVect, %<xSWork>);
}
%else
%assign u = LibBlockInputSignalAddr(0,"","",0)
%<y> = %<splFcnName>(%<numDimsArg>, %<u>, %<xSWork>);
%endif
%endif
%endif
%endfunction