/*
 * SCUMSUM  DSP Blockset function to compute cumulative sum.
 *
 *  Copyright 1995-2000 The MathWorks, Inc.
 *  $Revision: 1.14 $  $Date: 2000/06/14 14:27:57 $
 */
#define S_FUNCTION_NAME scumsum
#define S_FUNCTION_LEVEL 2

#define DATA_TYPES_IMPLEMENTED

#include "simstruc.h"
#include "dsptypes.h"

enum {NUM_ARGS=0};
enum {INPORT=0};
enum {OUTPORT=0};


static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, NUM_ARGS);
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return;

    /* Inputs: */
    if (!ssSetNumInputPorts(S, 1)) return;
    ssSetInputPortWidth(            S, INPORT, DYNAMICALLY_SIZED);
    ssSetInputPortComplexSignal(    S, INPORT, COMPLEX_INHERITED);
    ssSetInputPortDirectFeedThrough(S, INPORT, 1);
    ssSetInputPortReusable(        S, INPORT, 1);
    ssSetInputPortOverWritable(     S, INPORT, 1);

    /* Outputs: */
    if (!ssSetNumOutputPorts(S,1)) return;
    ssSetOutputPortWidth(        S, OUTPORT, DYNAMICALLY_SIZED);
    ssSetOutputPortComplexSignal(S, OUTPORT, COMPLEX_INHERITED);  
    ssSetOutputPortReusable(    S, OUTPORT, 1);

    ssSetNumSampleTimes(S, 1);
    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}


static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, FIXED_IN_MINOR_STEP_OFFSET);
}


static void mdlOutputs(SimStruct *S, int_T tid)
{
    const boolean_T inplace = (boolean_T)(ssGetInputPortBufferDstPort(S, INPORT) == OUTPORT);
    const boolean_T c0      = (boolean_T)(ssGetInputPortComplexSignal(S,INPORT) == COMPLEX_YES);
    int_T           width   = ssGetInputPortWidth(S,INPORT);

    if (inplace) {
        /* In-place algorithm: */

        if(!c0) {
            /* 
	     * Real Data: 
	     */
            real_T *y     = ssGetOutputPortRealSignal(S,OUTPORT);
            real_T *yprev = y++;  /* Skip over first element */
            while(--width > 0) {
                *y++ += *yprev++;
            }

        } else {
	    /* 
	     * Complex Data: 
	     */
            creal_T *y     = (creal_T *)ssGetOutputPortSignal(S,OUTPORT);
            creal_T *yprev = y++;  /* Skip over first element */
            while(--width > 0) {
                y->re     += yprev->re;
                (y++)->im += (yprev++)->im;
            }
        }

    } else {
        /* Discontiguous, or just does not share: */

        if(!c0) {
            /* 
	     * Real Data: 
	     */
            InputRealPtrsType  uptr  = ssGetInputPortRealSignalPtrs(S,INPORT);
            real_T            *y     = ssGetOutputPortRealSignal(S,OUTPORT);
            real_T            *yprev = y;
        
            *y++ = **uptr++;

            while(--width != 0) {
	        *y++ = **uptr++ + *yprev++;
            } 

        } else {
	    /* 
	     * Complex Data: 
	     */
            InputPtrsType  uptr  = ssGetInputPortSignalPtrs(S,INPORT);
            creal_T	      *y     = (creal_T *)ssGetOutputPortSignal(S,OUTPORT);
            creal_T       *yprev = y;

            *y++ = *((creal_T *)(*uptr++));

            while(--width != 0) {
                const creal_T *u = (creal_T *)(*uptr++);
                y->re     = u->re + yprev->re;
                (y++)->im = u->im + (yprev++)->im;
            }
        }   
    }
}


static void mdlTerminate(SimStruct *S)
{
}


#include "dsp_cplxhs11.c"   


#ifdef	MATLAB_MEX_FILE  
#include "simulink.c"    
#else
#include "cg_sfun.h"     
#endif
