/*
 * SDSPHST  S-Function for histogram function.
 *
 *  Copyright 1995-2000 The MathWorks, Inc.
 *  $Revision: 1.11 $   $Date: 2000/06/14 14:27:58 $
 */

#define S_FUNCTION_NAME sdsphst

#include "dsp_sim.h"

#define MIN_ARG   ssGetArg(S,0)
#define MAX_ARG   ssGetArg(S,1)
#define NBINS_ARG ssGetArg(S,2)
#define NUM_ARGS  3


#ifdef MATLAB_MEX_FILE
#define MDL_CHECK_PARAMETERS
static void mdlCheckParameters(SimStruct *S)
{
    int_T  i;
    real_T d;

    /* Check min/max/nbins: */
    if ((mxGetNumberOfElements(MIN_ARG) != 1)  ||
        (mxGetNumberOfElements(MAX_ARG) != 1)  ||
        (mxGetNumberOfElements(NBINS_ARG) != 1) ) {
        THROW_ERROR(S, "Minimum, maximum, and number of bins must be scalar values");
    }

	/* Check nbins: */
    d = mxGetPr(NBINS_ARG)[0];
    i = (int_T)d;
    if ((i != d) || (d <= 0)) {
      THROW_ERROR(S, "Number of bins must be a non-zero integer");
    }

    /* Check min/max: */
    if (mxGetPr(MIN_ARG)[0] >= mxGetPr(MAX_ARG)[0]) {
	    THROW_ERROR(S, "Minimum must be less than maximum");
    }
}
#endif


static void mdlInitializeSizes(SimStruct *S)
{
    int_T Nbins;

    ssSetNumSFcnParams(S, NUM_ARGS);

#if defined(MATLAB_MEX_FILE)
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return;
    mdlCheckParameters(S);
    if (ssGetErrorStatus(S) != NULL) return;
#endif

    Nbins = (int_T) mxGetPr(NBINS_ARG)[0];

    ssSetNumInputs(        S, DYNAMICALLY_SIZED);
    ssSetNumOutputs(       S, Nbins);
    ssSetDirectFeedThrough(S, 1);
    ssSetNumSampleTimes(   S, 1);
    ssSetOptions(          S, SS_OPTION_EXCEPTION_FREE_CODE |
                              SS_OPTION_USING_ssGetUPtrs);
}


static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTimeEvent(S, 0, INHERITED_SAMPLE_TIME);
    ssSetOffsetTimeEvent(S, 0, 0.0);
}


static void mdlInitializeConditions(real_T *x0, SimStruct *S)
{
}


static void mdlOutputs(real_T *y, const real_T *x, const real_T *u, 
                       SimStruct *S, int_T tid)
{
        UPtrsType    uptr   = ssGetUPtrs(S);
        int_T		 width    = ssGetNumInputs(S);
        const real_T umin   = mxGetPr(MIN_ARG)[0];
        const real_T umax   = mxGetPr(MAX_ARG)[0];
        int_T        Nbins  = (int_T) mxGetPr(NBINS_ARG)[0];
        real_T       idelta = Nbins/(umax-umin);
		  int_T        i;
        

		for (i=0; i<Nbins; i++) {
			y[i] = 0.0;
		}

		/*
       * Compute histogram:
       */
		while(width-- > 0) {
			real_T val   = **uptr++;
			if (val <= umin) {
			  i = 0;
			} else if (val > umax) {
			  i = Nbins-1;
			} else {
			  i = (int_T)(ceil((val-umin)*idelta)-1) ;
			}
			(*(y + i))++;
		}
}


static void mdlUpdate(real_T *x, const real_T *u, SimStruct *S, int_T tid)
{
}


static void mdlDerivatives(real_T *dx, const real_T *x, const real_T *u, 
                           SimStruct *S, int_T tid)
{
}


static void mdlTerminate(SimStruct *S)
{
}


#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif
