%% File : sfun_lookupnd.tlc generated from sfun_lookupnd.ttlc revsion 1.6 %% $Date: 2000/05/17 20:17:04 $ %% %% Rob Aberg, 13-Aug-1999 %% Copyright 1990-2000 The MathWorks, Inc. %% %% Abstract: N-D Lookup table with various options. %implements sfun_lookupnd "C" %% Function: BlockInstanceSetup =================================================== %% Abstract: %% Have mdlhdr.tlc include rtlibsrc.h %% %function BlockInstanceSetup(block, system) void %if SFcnParamSettings.vectorInputFlag == 0 %assign numDims = NumDataInputPorts %else %assign numDims = LibBlockInputSignalWidth(0) %endif %switch SFcnParamSettings.interpMethod %case 2 %if numDims > 2 %assign ::CompiledModel.IncludeLibsrc = 1 %endif %break %case 3 %assign ::CompiledModel.IncludeLibsrc = 1 %break %default %break %endswitch %endfunction %% BlockInstanceData ========================================================== %% Abstract: %% Create persistant data for PWork Vector. %% %function BlockInstanceData(block, system) Output /* Look-Up Table (N-D) (LookupND) */ /* Block: % */ %% %assign tabSize = LibBlockParameterSize(table) %if SFcnParamSettings.vectorInputFlag == 0 %assign numDims = NumDataInputPorts %else %assign numDims = LibBlockInputSignalWidth(0) %endif %assign ttype = LibBlockOutputSignalDataTypeName(0,"") %assign dims = SFcnParamSettings.tabDims %assign biggestDim = dims[0] %if numDims > 1 %foreach idx = % %if dims[%] > biggestDim %assign biggestDim = dims[%] %endif %endforeach %endif %assign biggestDim = CAST("Number", biggestDim) %assign tnumYWorkElements = [0:%] %assign tnumYWorkElements[numDims] = 0 %assign tnumYWorkElements[numDims-1] = 1 %foreach idx = % %assign yidx = numDims-2 - idx %assign tnumYWorkElements[%] = tnumYWorkElements[%] * \ dims[%] %endforeach %assign largestVec = CAST("Number", tnumYWorkElements[0]) %if UsingMalloc % = malloc(% * sizeof(%)); rt_VALIDATE_MEMORY(%, %); % = malloc(% * sizeof(%)); rt_VALIDATE_MEMORY(%, %); %if SFcnParamSettings.interpMethod == 3 %% %% work vectors for spline interpolation %% % = malloc( sizeof(SplineWorkVect) ); rt_VALIDATE_MEMORY(%, %); % = malloc(% * ... sizeof(%)); rt_VALIDATE_MEMORY(%, %); % = malloc(% * ... sizeof(%)); rt_VALIDATE_MEMORY(%, %); % = malloc(% * ... sizeof(%)); rt_VALIDATE_MEMORY(%, %); % = malloc(% * ... sizeof(%)); rt_VALIDATE_MEMORY(%, %); % = malloc(% * ... sizeof(%)); rt_VALIDATE_MEMORY(%, %); %endif %else { static % uLambdasBuffer[%] ; static % uVectBuffer[%] ; %if SFcnParamSettings.interpMethod == 3 static SplineWorkVect splWork; static % yyABuffer[%] ; static % yyBBuffer[%] ; static % yy2Buffer[%] ; static % upBuffer[%] ; static % y2Buffer[%] ; %endif %assign vCast = "(void *) " % = %&uLambdasBuffer[0]; % = %&uVectBuffer[0]; %if SFcnParamSettings.interpMethod == 3 % = %&splWork; % = %&yyABuffer[0]; % = %&yyBBuffer[0]; % = %&yy2Buffer[0]; % = %&upBuffer[0]; % = %&y2Buffer[0]; %endif } %endif %endfunction %% Start ====================================================================== %% Abstract: %% Initialize the state information (first input & time) %% %function Start(block, system) Output /* Look-Up Table (N-D) (LookupNDInterp) */ /* Block: % */ %if SFcnParamSettings.vectorInputFlag == 0 %assign numEl = NumDataInputPorts %else %assign numEl = LibBlockInputSignalWidth(0) %endif /* index search result storage explicit initialization */ %assign rollVars = ["Mode"] %assign rollRegion = [0:%] %roll idx = rollRegion, lcv = RollThreshold, block, "Roller", rollVars %assign m = LibBlockMode("", lcv, idx) % = 0; %endroll /* maxIdx initialization */ %assign dims = SFcnParamSettings.tabDims %assign rollVars = ["IWork"] %assign rollRegion = [0:%] %roll idx = rollRegion, lcv = RollThreshold, block, "Roller", rollVars %assign iw = LibBlockIWork(maxIdx, "", lcv, idx) % = %; %endroll %if numEl > 2 || SFcnParamSettings.interpMethod != 2 /* dimSizes initialization */ %assign tdimSizes = dims %assign tdimSizes[0] = 1 %foreach i = % %assign tdimSizes[i+1] = tdimSizes[i]*dims[i] %endforeach %assign rollVars = ["IWork"] %assign rollRegion = [0:%] %roll idx = rollRegion, lcv = RollThreshold, block, "Roller", rollVars %assign iw = LibBlockIWork(dimSizes, "", lcv, idx) % = %; %endroll %endif %if SFcnParamSettings.interpMethod == 3 %% %% calculate needed size of work vectors %if SFcnParamSettings.vectorInputFlag == 0 %assign numDims = NumDataInputPorts %else %assign numDims = LibBlockInputSignalWidth(0) %endif %assign tnumYWorkElements = [0:%] %assign tnumYWorkElements[numDims] = 0 %assign tnumYWorkElements[numDims-1] = 1 %foreach idx = % %assign yidx = numDims-2 - idx %assign tnumYWorkElements[%] = tnumYWorkElements[%] * \ dims[%] %endforeach /* numYWorkElements initialization */ %assign rollVars = ["IWork"] %assign rollRegion = [0:%] %roll idx = rollRegion, lcv = RollThreshold, block, "Roller", rollVars %assign iw = LibBlockIWork(numYWorkElements, "", lcv, idx) % = %; %endroll /* work vector bundle initialization */ %assign tsplWork = LibBlockPWork(splWork, "", "", 0) { SplineWorkVect *splWk = (SplineWorkVect *) %; splWk->uLambdas = %; splWk->uVect = %; splWk->yyA = %; splWk->yyB = %; splWk->yy2 = %; splWk->up = %; splWk->y2 = %; splWk->Indices = &%; splWk->numYWorkElements = &%; splWk->maxIdx = &%; splWk->bpIndices = %; splWk->bpData = %; splWk->tableData = %; splWk->extrapMethod = %; } %endif %endfunction %% Function: Outputs ========================================================== %% Abstract: %% Perform indicated interpolation, flat or linear %% %function Outputs(block, system) Output /* Look-Up Table (N-D) (LookupNDInterp) */ /* Block: % */ { %assign ttype = LibBlockOutputSignalDataTypeName(0,"") %if SFcnParamSettings.vectorInputFlag == 0 %assign numEl = NumDataInputPorts %else %assign numEl = LibBlockInputSignalWidth(0) %endif /* retrieve work vectors */ %assign declULambda = "% *uLambda" %assign declUVect = "% *uVect" %assign vCast = "(% *) " % = %%; %if numEl > 1 % = %%; %endif %if (numEl > 1 && SFcnParamSettings.interpMethod == 1) || ... (numEl > 2 && SFcnParamSettings.interpMethod == 2) int_T *dimSizes = &%; %endif %if numEl > 1 /* collect inputs */ %foreach idx = numEl %if SFcnParamSettings.vectorInputFlag == 0 uVect[%] = %; %else uVect[%] = %")>; %endif %endforeach %endif /* do index search for each input */ { %assign declBpData = "const % *bpData" %if numEl > 1 %assign iVar = "i" %if SFcnParamSettings.searchMode > 1 % lambda; %endif int_T %; for (%= 0; % < %; %++) { int_T bpBaseIdx = \ %", "", "")>; % = %; int_T maxIdx = \ %", "", "")>; %assign istr = "%" %assign istr2 = "2*%" %assign istr21 = "2*%+1" %else % = %; int_T maxIdx = \ %; %assign istr = "0" %assign istr2 = "0" %assign istr21 = "1" %endif %% %if SFcnParamSettings.rangeErrorMode < 3 || ... SFcnParamSettings.searchMode > 1 %if numEl == 1 % lambda; %endif %if SFcnParamSettings.searchMode != 1 || ... SFcnParamSettings.extrapMethod != 1 boolean_T bpFound = false; %endif %if numEl == 1 %assign idx = 0 %if SFcnParamSettings.vectorInputFlag == 0 % u = %; %else % u = %")>; %endif %else % u = uVect[%]; %endif %if SFcnParamSettings.searchMode > 1 %% is this an actual search? %if SFcnParamSettings.cacheBpFlag == 1 int_T index = \ %", "", "")>; \ /* get previous index */ %else int_T index = 0; %endif %elseif SFcnParamSettings.extrapMethod != 1 int_T index; %endif %endif %if SFcnParamSettings.extrapMethod == 1 /* clipping */ %if SFcnParamSettings.rangeErrorMode != 3 %if SFcnParamSettings.searchMode == 1 u = (u < bpData[0]) ? bpData[0] : ((u > bpData[maxIdx]) ? bpData[maxIdx] : u); %else if (u < bpData[0]) { index = 0; lambda = 0.0; bpFound = true; } else if (u > bpData[maxIdx]) { index = maxIdx - 1; lambda = 1.0; bpFound = true; } %endif %endif %else /* extrapolation (check) */ if (u < bpData[0]) { index = 0; lambda = (u - bpData[0]) / (bpData[1] - bpData[0]); bpFound = true; } else if (u > bpData[maxIdx]) { index = maxIdx - 1; lambda = (u - bpData[maxIdx-1]) / ... (bpData[maxIdx] - bpData[maxIdx-1]); bpFound = true; } %endif %% %switch (SFcnParamSettings.searchMode) %case 1 %if SFcnParamSettings.extrapMethod > 1 if (bpFound == false) { %endif /* directly calculate index and fraction */ uLambda[%] = (u - bpData[0]) / (bpData[1] - bpData[0]); %", "", "")> = (int_T) uLambda[%]; if ( %", "", "")> == maxIdx ) { %", "", "")>--; uLambda[%] = 1.0; } else { uLambda[%] -= (%) %", "", "")>; } %if SFcnParamSettings.extrapMethod > 1 } else { %", "", "")> = index; uLambda[i] = lambda; } %endif %break %case 2 /* in-range linear search for [ u ) */ while (bpFound == false) { lambda = (u - bpData[index]) / (bpData[index+1] - bpData[index]); /* check result */ if (lambda >= 0.0 && lambda < 1.0 ) { bpFound = true; } else if (lambda > 1.0) { index++; } else if (lambda < 0.0) { index--; } else if (lambda == 1.0) { bpFound = true; if ( index < (maxIdx-1) ) { index++; lambda = 0.0; } } } %", "", "")> = index; uLambda[%] = lambda; %break %case 3 /* in-range binary search for [ u ) */ if (bpFound == false) { int_T bottom = 0; int_T top = maxIdx; while (bpFound == false) { if (u < bpData[index]) { top = index - 1; index = (top + bottom) / 2; } else if (u <= bpData[index+1]) { bpFound = true; if ( u == bpData[index+1] ) { index++; } } else { bottom = index + 1; index = (top + bottom) / 2; } } if (index == maxIdx) { index--; lambda = 1.0; } else { lambda = (u - bpData[index]) / (bpData[index+1] - bpData[index]); } } %", "", "")> = index; uLambda[%] = lambda; %endswitch %% %if numEl > 1 } %endif } %assign numDims = SIZE(SFcnParamSettings.tabDims,1) %assign y = LibBlockOutputSignal(0, "0", "", "") %assign dims = SFcnParamSettings.tabDims %assign tdimSizes = dims %assign tdimSizes[0] = 1 %foreach i = % %assign tdimSizes[i+1] = tdimSizes[i]*dims[i] %endforeach %switch SFcnParamSettings.interpMethod %case 1 %% %% FLAT interpolation (i.e., don't interpolate) %% %if NumDataInputPorts > 1 { /* flat, no interpolation - use point at beginning of interval */ int_T offset; %foreach idx = NumDataInputPorts %if tdimSizes[idx]==1 %if idx == 0 offset = %; %else offset = offset + %; %endif %else offset = offset + dimSizes[%] * %", "", "")>; %endif %endforeach % = %; } %else % = %", "", "")>; %endif %break %case 2 %% %% LINEAR interpolation %% %switch numDims %case 1 /* Linear 1-D interpolation */ { int_T offset = \ %; % = % + ... uLambda[0]*(% - ... %); } %break %case 2 %assign ttype = LibBlockOutputSignalDataTypeName(0,"") %assign t1 = LibBlockParameter(table, "offset", "", "") %assign t2 = LibBlockParameter(table, "offset+1", "", "") /* Linear 2-D interpolation */ { int_T offset = \ % + ... % * %; % ylower; % yupper; ylower = % + uLambda[0]* (% - %); offset += %; yupper = % + uLambda[0]* (% - %); % = ylower + uLambda[1]*(yupper - ylower); } %break %default %assign t = LibBlockParameterAddr(table,"","",0) /* Linear %-D interpolation */ % = rt_LookupLinearInterpND_%(%, 0, &%, uLambda, dimSizes, %); %endswitch %break %case 3 %% %% SPLINE interpolation %% %% /* Natural Spline %-D interpolation */ % = rt_LookupSplineInterpND_%(%, (SplineWorkVect *)%); %break %endswitch } %endfunction %% %% Function: Terminate ========================================================= %% Abstract: %% For malloc'ed work vectors, free memory %% %function Terminate(block, system) Output %if UsingMalloc /* Look-Up Table (N-D) (LookupNDInterp) */ /* Block: % */ #if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE) rt_FREE(%); rt_FREE(%); %if SFcnParamSettings.interpMethod == 3 rt_FREE(%); rt_FREE(%); rt_FREE(%); rt_FREE(%); rt_FREE(%); rt_FREE(%); %endif #endif %endif %endfunction %% [EOF] sfun_lookupnd.tlc