%%
%%
%%
%%Copyright1994-2013TheMathWorks,Inc.
%%
%%Abstract:1D-Lookupblocktargetfile
 
%implements Lookup "C"
 
%include "fixptlook_support.tlc"
%include "fixptlook_search.tlc"
%include "fixptlook1D.tlc"
 
%%Function:BlockTypeSetup====================================================
%%Abstract:
%%
%function BlockTypeSetup(block, system) void
 
%endfunction
 
%%Function:BlockInstanceSetup================================================
%%Abstract:
%%
%function BlockInstanceSetup(block, system) void
  %if block.InFixptMode
    %%
    %% Call the fixed-point setup function
    %%
    %<FixPt_Setup(block, system)>
    %%
  %else
    %<LibBlockSetIsExpressionCompliant(block)>
  %endif
  %if GenerateASAP2
    %% Create a parameter group for ASAP2 data definition
    %assign group = SLibCreateParameterGroup(block,"Lookup1D")
    %assign tmpVar = SLibAddMember(block,group,InputValues)
    %assign tmpVar = SLibAddMember(block,group,Table)
  %endif
%endfunction
 
%%Function:genLookupFcnFromTfl=============================================
%%
%function genLookupFcnFromTfl(outputDataType, addrInputValues, numInputValues, u, addrOutputValues) void
 
    %createrecord FcnRec{Name "rt_Lookup"; RetTypeId outputDataType; NumArgs 4}
    %addtorecord FcnRec ArgList{Expr "%<addrInputValues>"; TypeId outputDataType; IsPtr 1; IsCplx 0; IsConst 0}
    %addtorecord FcnRec ArgList{Expr "%<numInputValues>"; TypeId tSS_INTEGER; IsPtr 0; IsCplx 0; IsConst 0}
    %addtorecord FcnRec ArgList{Expr "%<u>"; TypeId outputDataType; IsPtr 0; IsCplx 0; IsConst 0}
    %addtorecord FcnRec ArgList{Expr "%<addrOutputValues>"; TypeId outputDataType; IsPtr 1; IsCplx 0; IsConst 0}
 
    %return "%<LibGenFcnCall(FcnRec)>"
 
%endfunction %% genLookupFcnFromTfl
 
%%Function:Outputs==========================================================
%%Abstract:
%%Y=lookup(U);
%%
%function Outputs(block, system) Output
  %if block.InFixptMode
    %%
    %assign y0IsComplex = LibBlockOutputSignalIsComplex(0)
    %%
    %% if input (and Output) are complex then two cases to handle
    %% otherwise only one
    %%
    %assign casesToHandle = 1 + y0IsComplex
    %%
    %% Get input data type
    %%
    %assign u0DT = FixPt_GetInputDataTypeWithBoolReplace(0)
    %%
    %% Get output data type
    %%
    %assign y0DT = FixPt_GetOutputDataType(0)
    %%
    %% create header comment
    %%
    %openfile commentBuffer
    %%
    %% add general comments
    %%
    %<FixPt_GeneralComments()>/
    %%
    %% comment on modes
    %%
     * Lookup Method: %<FixPtLookUpMethodStr>
     *
    %%
    %% determine if the XData is inlined and evenly spaced
    %%
    %if FixPt_ParameterCouldBeInlined(InputValues, "", "", 0)
        %assign xDataEvenSpaceInfo = FixPt_GetBreakPointInfo(InputValues.Value)
    %else
        %assign xDataEvenSpaceInfo = FixPt_BreakPointInfoDefault()
    %endif
    %%
    %% optimize trivial interpolation case
    %%
    %assign lookUpMethodStr = FixPtLookUpMethodStr
    %%
    %if lookUpMethodStr == "Linear_Endpoint"
        %%
        %if !FixPt_DataTypeIsFloat(u0DT) && ISEQUAL(xDataEvenSpaceInfo.spacingValue,1)
            %assign lookUpMethodStr = "Below"
            %%
             * X table is inlined, evenly space, and the spacing of the stored
             * integers is the trivial case of plus one. Therefore, interpolation
             * can be replaced by a simple indexing operation.
             *
        %endif
        %%
    %endif
    %%
    %% add comments about parameters
    %%
    %if xDataEvenSpaceInfo.evenlySpaced
        * XData is inlined and evenly spaced, so the algorithm only needs
        * the value of the first element, the last element, and the spacing.
        * For efficiency, XData is excluded from the generated code.
    %else
     * XData parameter uses the same data type and scaling as Input0
    %endif
    %%
     * YData parameter uses the same data type and scaling as Output0
    %%
    %% END: header comment
    %%
    %closefile commentBuffer
    %%
    %<LibCacheBlockComment(block,commentBuffer)>/
    %%
    %% declare local variables as needed
    %%
    %if lookUpMethodStr == "Linear_Endpoint"
        %%
      %assign searchMethod = "Below"
      %assign iLeftLabel = ""
            %assign iRghtLabel = ""
      %%
    %elseif lookUpMethodStr == "Below"
      %%
      %assign searchMethod = "Below"
      %assign iLeftLabel = "iLeft"
        %assign iRghtLabel = ""
      %assign iToUseForOutput = iLeftLabel
      %%
    %elseif lookUpMethodStr == "Above"
      %%
        %assign searchMethod = "Above"
        %assign iLeftLabel = ""
      %assign iRghtLabel = "iRght"
        %assign iToUseForOutput = iRghtLabel
      %%
    %elseif lookUpMethodStr == "Nearest"
      %%
        %assign searchMethod = "Near"
      %assign iLeftLabel = "iLeft"
        %assign iRghtLabel = ""
      %assign iToUseForOutput = iLeftLabel
      %%
    %else
      %openfile errTxt
 
        The lookup method: %<lookUpMethodStr> is not supported
        for code generation.
 
        Block: '%<SLibBlkName(block)>'
     
      %closefile errTxt
      %exit %<errTxt>
      %%
    %endif
    %%
    %if iLeftLabel != "" || iRghtLabel != ""
      {
    %endif
    %%
    %if iLeftLabel != ""
        %%
        %<FixPt_uint_label> %<iLeftLabel>;
 
    %endif
    %%
    %if iRghtLabel != ""
        %%
        %<FixPt_uint_label> %<iRghtLabel>;
 
    %endif
    %%
    %% Roll around signal width
    %%
    %assign rollVars = ["U", "Y"]
    %%
    %roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
        %%
        %% Get input
        %%
        %assign u0Label = LibBlockInputSignal(0, "", lcv, sigIdx)
        %%
        %% lookup method Linear_Endpoint
        %%
        %if lookUpMethodStr == "Linear_Endpoint"
            %%
            %% Get output (if complex, get the whole structure)
            %%
            %assign y0Label = LibBlockOutputSignal(0, "", lcv, sigIdx)
            %%
            %<FixPt_SearchAndInterpolate(...
                             y0Label,y0DT,...
                             u0Label,u0DT,...
                             Table, y0DT,-1,...
              InputValues, u0DT, -1, xDataEvenSpaceInfo,...
                             FixPtRoundingMode,FixPtSaturationMode)>/
        %%
        %% lookup method BELOW
        %% lookup method ABOVE
        %% lookup method NEAREST
        %%
        %else
            %%
            %% find indices
            %%
            %% NOTE, there is NO scalar expansion so having the search
            %% inside the roll-loop is NOT inefficient.
            %%
            %<FixPt_IndexSearch(iLeftLabel,iRghtLabel,...
                                u0Label,u0DT,...
                                InputValues, u0DT,...
                                xDataEvenSpaceInfo,-1,...
                                searchMethod)>/
     
            %foreach iCase = casesToHandle
                %%
                %if iCase == 0
                    %%
                    %assign riSigIdx = tRealPart + STRING(sigIdx)
                    %assign riParmIdx = "re0"
                %else
                    %assign riSigIdx = tImagPart + STRING(sigIdx)
                    %assign riParmIdx = "im0"
                %endif
                %%
                %assign y0Label = LibBlockOutputSignal(0, "", lcv, riSigIdx)
                %%
                %<y0Label> = %<LibBlockParameter(Table, iToUseForOutput, "", riParmIdx)>;
                %%
            %endforeach
        %endif
    %endroll
    %%
    %if iLeftLabel != "" || iRghtLabel != ""
      }
    %endif
    %%
  %else
    %%
    %% Classic (non-fixpt) lookup
    %%
    %assign outputDataType = LibBlockOutputSignalAliasedThruDataTypeId(0)
    %assign addrInputValues = LibBlockParameterBaseAddr(InputValues)
    %assign addrOutputValues = LibBlockParameterBaseAddr(Table)
    %assign numInputValues = SIZE(InputValues.Value, 1)
    %%
    %assign rollVars = ["U", "Y"]
    %roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars
      %assign u = LibBlockInputSignal(0, "", lcv, sigIdx)
      %assign y = LibBlockOutputSignal(0, "", lcv, sigIdx)
      %%
      %if (ParamSettings.ZeroTechnique == "AverageValue" || ...
    ParamSettings.ZeroTechnique == "Middle_Value")
    %%
    %% Code to deal with zero input. The value of output
    %% when input is zero is precalculated and saved in
    %% s->output_at_zero
    %%
    if (%<u> == 0.0) {
    %<y> = %<LibBlockParameter(OutputAtZero, "", "", 0)>;
    } else {
      %endif
      %% Output the following independent of whether NormalInterp or
      %% one of the other ZeroTechniques
        %<y> = ...
            %<genLookupFcnFromTfl(outputDataType, addrInputValues, numInputValues, u, addrOutputValues)>;
      %if (ParamSettings.ZeroTechnique == "AverageValue" || ...
    ParamSettings.ZeroTechnique == "Middle_Value")
    }
      %endif
    %endroll
  %endif
 
%endfunction
 
%%Function:BlockOutputSignal=================================================
%%Abstract:
%%Returnanoutputexpression.Thisfunction*may*
%%beusedbySimulinkwhenoptimizingtheBlockIOdatastructure.
%%
%function BlockOutputSignal(block,system,portIdx,ucv,lcv,idx,retType) void
  %if !block.InFixptMode
    %switch retType
      %case "Signal"
    %assign outputDataType = LibBlockOutputSignalAliasedThruDataTypeId(0)
    %assign addrInputValues = LibBlockParameterBaseAddr(InputValues)
    %assign addrOutputValues = LibBlockParameterBaseAddr(Table)
    %assign numInputValues = SIZE(InputValues.Value, 1)
    %assign u = LibBlockInputSignal(0, ucv, lcv, idx)
    %if (ParamSettings.ZeroTechnique == "AverageValue" || ...
      ParamSettings.ZeroTechnique == "Middle_Value")
      %%START_ASSERT
      %assign errTxt = "Expression output is not valid."
      %<LibBlockReportFatalError(block,errTxt)>
      %%END_ASSERT
    %endif
    %return ...
      "%<genLookupFcnFromTfl(outputDataType, addrInputValues, numInputValues, u, addrOutputValues)>"
 
    %%START_ASSERT
      %default
    %assign errTxt = "Unsupported return type: %<retType>"
    %<LibBlockReportError(block,errTxt)>
    %%END_ASSERT
    %endswitch
  %endif
%endfunction
 
%%[EOF]look_up.tlc