⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 moveint.c

📁 Proakis《contemporarycommunication systems using matlab》matlab源代码
💻 C
字号:
/*
 * MOVEINT   A SIMULINK moving integration
 *
 *           Syntax:  [sys, x0] = sbuffer(t, x, u, flag, In_length, Time_window, Sample_time, Method)
 *
 *      In-length: the vector length of the input vector.
 *      Time_window: int_t^(t+T) f(x) dx, the scale T, window size of the integration.
 *      Sample_time: sampling time of the integration. This is a discrete-time block.
 *      Method: integration method. Could be choose from: forward, backward, first_order.
 *
 * Wes Wang Dec. 8, 1994
 * Copyright (c) 1994-96 by The MathWorks, Inc.
 * All Rights Reserved
 * $Revision: 1.1 $  $Date: 1996/04/01 19:03:36 $
 */

#define S_FUNCTION_NAME moveint

#ifdef MATLAB_MEX_FILE
#include <stdio.h>    /* needed for declaration of sprintf */
#include "mex.h"      /* needed for declaration of mexErrMsgTxt */
#endif

/*
 * need to include simstruc.h for the definition of the SimStruct and
 * its associated macro definitions.
 */

#include "simstruc.h"

/*
 * Defines for easy access of the input parameters
 */

#define NUM_ARGS   4
#define IN_LENGTH      ssGetArg(S,0)
#define TIME_WINDOW        ssGetArg(S,1)
#define SAMPLE_TIME        ssGetArg(S,2)
#define METHOD     ssGetArg(S,3)

/*
 * mdlInitializeSizes - called to initialize the sizes array stored in
 *                      the SimStruct.  The sizes array defines the
 *                      characteristics (number of inputs, outputs,
 *                      states, etc.) of the S-Function.
 */

static void mdlInitializeSizes(S)
    SimStruct *S;
{
    /*
     * Set-up size information.
     */ 
    
    if (ssGetNumArgs(S) == NUM_ARGS) {
      int in_length, num_points;
    char method[2];
/*    char err_msg[256];
 */
    
    if ((mxGetN(IN_LENGTH) != 1) || (mxGetM(IN_LENGTH) != 1)) {
#ifdef MATLAB_MEX_FILE
           mexErrMsgTxt("The inout vector length must be a scalar");
#endif
     }

       if ((mxGetN(TIME_WINDOW) != 1) || (mxGetM(TIME_WINDOW) != 1)) {
#ifdef MATLAB_MEX_FILE
       mexErrMsgTxt("The integration time window must be a scalar");
#endif
 }

       if ((mxGetN(SAMPLE_TIME)*mxGetM(SAMPLE_TIME) != 1) &&
       (mxGetN(SAMPLE_TIME)*mxGetM(SAMPLE_TIME) != 2)) {
#ifdef MATLAB_MEX_FILE
         mexErrMsgTxt("The sample time must be a scalar or a vector of length 2");
#endif
     }

       if (mxGetM(METHOD) != 1) {
#ifdef MATLAB_MEX_FILE
            mexErrMsgTxt("Integration method must be a string");
#endif
  }
       
        in_length  = mxGetPr(IN_LENGTH)[0];
     num_points = (int)(mxGetPr(TIME_WINDOW)[0] / mxGetPr(SAMPLE_TIME)[0] + 0.49) + 1;
       if (num_points <= 2) {
#ifdef MATLAB_MEX_FILE
        mexErrMsgTxt("The integration time window must be greater than sample time.");
#endif
        } else if (in_length < 1) {
#ifdef MATLAB_MEX_FILE
           mexErrMsgTxt("The input vector length must be a positive number.");
#endif
   }
       method[0] = (char)mxGetPr(METHOD)[0];
   method[1] = (char)mxGetPr(METHOD)[1];   
        
   ssSetNumContStates(    S, 0);
   ssSetNumDiscStates(    S, 0);
   ssSetNumInputs(        S, in_length);
   ssSetNumOutputs(       S, in_length);
   if ((method[0] == 'f') && (method[1] == 'o'))
       ssSetDirectFeedThrough(S, 0);
   else
       ssSetDirectFeedThrough(S, 1);
   ssSetNumInputArgs(     S, NUM_ARGS);
   ssSetNumSampleTimes(   S, 1);
   ssSetNumRWork(         S, in_length*(num_points + 1) + 1);
      /* storage: t, points, last_integration_value */
   ssSetNumIWork(         S, 2);
   /* Total_points=num_points, current points */
   ssSetNumPWork(         S, 0);
/*    sprintf(err_msg, "Initialization num_points = %i, in_length = %i\n",num_points, in_length);
    mexPrintf(err_msg);
 */
    } else {
#ifdef MATLAB_MEX_FILE
      char err_msg[256];
      sprintf(err_msg, "Wrong number of input arguments passed to S-function MEX-file.\n"
             "%d input arguments were passed in when expecting %d input arguments.\n", ssGetNumArgs(S) + 4, NUM_ARGS + 4);
   mexErrMsgTxt(err_msg);
#endif
    }
}

/*
 * mdlInitializeSampleTimes - initializes the array of sample times stored in
 *                            the SimStruct associated with this S-Function.
 */

static void mdlInitializeSampleTimes(S)
    SimStruct *S;
{
    double sampleTime, offsetTime;

    /*
     * Note, blocks that are continuous in nature should have a single
     * sample time of 0.0.
     */

    sampleTime = mxGetPr(SAMPLE_TIME)[0];
    if ((mxGetN(SAMPLE_TIME) * mxGetM(SAMPLE_TIME)) == 2)
    offsetTime = mxGetPr(SAMPLE_TIME)[1];
    else
   offsetTime = 0.;
    
    ssSetSampleTimeEvent(S, 0, sampleTime);
    ssSetOffsetTimeEvent(S, 0, offsetTime);
}

/*
 * mdlInitializeConditions - initializes the states for the S-Function
 */

static void mdlInitializeConditions(x0, S)
    double *x0;
    SimStruct *S;
{
    int in_length = mxGetPr(IN_LENGTH)[0];
    int num_points = (int)(mxGetPr(TIME_WINDOW)[0] / mxGetPr(SAMPLE_TIME)[0] + 0.49) + 1;
    
    double *last_time  = ssGetRWork(S);
    double *storage_point = ssGetRWork(S) + 1;
    double *integ_value   = ssGetRWork(S) + in_length * num_points + 1;
    
    int *cur_point       = ssGetIWork(S);
    int i;
    
    /* 
     * Initialize all storage and integration values
     */

    for (i = 0; i < in_length * (num_points + 1); i++)
      *storage_point++ = 0.;
    *last_time = -1;
    /*
     * IWork
     */
    
    *cur_point++       = num_points;
    *cur_point         = 0;
}

/*
 * mdlOutputs - computes the outputs of the S-Function
 */

static void mdlOutputs(y, x, u, S, tid)
    double *y, *x, *u;
    SimStruct *S;
    int tid;
{
    int *num_points     = ssGetIWork(S);
    int *cur_point      = ssGetIWork(S)+1;
    int in_length       = mxGetPr(IN_LENGTH)[0];

    double *last_time = ssGetRWork(S);
    double *storage_point = ssGetRWork(S) + 1;
    double *integ_value   = ssGetRWork(S) + (in_length * (*num_points) + 1);
    
    double sample_time = mxGetPr(SAMPLE_TIME)[0];

    double current_time;
    int i;
    char method[2];

    current_time  = ssGetT(S);
     method[0] = (char)mxGetPr(METHOD)[0];
   method[1] = (char)mxGetPr(METHOD)[1];   

        if (*num_points > 0) {
    if ((current_time - *last_time) > sample_time/1000000.) {
/*        char err_msg[256];        */
        int increament, point_before, point_after;

        point_before = (*num_points + *cur_point - 1) % (*num_points);
        point_after  = (*cur_point + 1) % (*num_points);
/*    sprintf(err_msg, "Output: num_points = %i, in_length = %i\n",*num_points, in_length);
    mexPrintf(err_msg);
 */
        for (i=0; i<in_length; i++) {
            increament = (*num_points) * i;
/*    sprintf(err_msg, "cur_point = %i, point_before = %i, point_after %i, increament %i\n",*cur_point, point_before, point_after, increament);
    mexPrintf(err_msg);
 */
         if ((method[0] == 'f') && (method[1] == 'o')) {
/*    sprintf(err_msg, "integ_value = %f, storage_before = %f, current_point = %f \n", integ_value[i], storage_point[point_before+increament], storage_point[*cur_point+increament]);
    mexPrintf(err_msg);
 */
              integ_value[i] = integ_value[i]
                     + (storage_point[point_before + increament]
                        - storage_point[*cur_point + increament]) * sample_time;
             } else if ((method[0] == 'b') && (method[1] == 'a')) {
              integ_value[i] = integ_value[i]
                    + (u[i]
                        - storage_point[point_after + increament]) * sample_time;
         } else {
                    integ_value[i] = integ_value[i]
                    + (u[i]
                        + storage_point[point_before + increament]
                        - storage_point[(*cur_point) + increament]                    
                        - storage_point[point_after + increament]) * sample_time / 2;
             }
            storage_point[(*cur_point) + increament] = u[i];
        }
        *cur_point = point_after;
        *last_time = current_time;
    } else {
/*        char err_msg[256];        */
        for (i=0; i<in_length; i++) {
           int increament;
            increament = (*num_points) * i;
/*    sprintf(err_msg, "\n cur_point = %i, increament %i\n",*cur_point, increament);
    mexPrintf(err_msg);
 */
             if ((method[0] == 'f') && (method[1] == 'o')) {
         } else if ((method[0] == 'b') && (method[1] == 'a')) {
              integ_value[i] = integ_value[i]
                    + (u[i]
                        - storage_point[*cur_point + increament]) * sample_time;
          } else {
                    integ_value[i] = integ_value[i]
                    + (u[i]
                        - storage_point[(*cur_point) + increament]) * sample_time / 2;
            }
            storage_point[(*cur_point) + increament] = u[i];
        }
    }
     }
    for (i = 0; i<in_length; i++)
        y[i] = integ_value[i];
}

/*
 * mdlUpdate - computes the discrete states of the S-Function
 */

static void mdlUpdate(x, u, S, tid)
    double *x, *u;
    SimStruct *S;
    int tid;
{
}

/*
 * mdlDerivatives - computes the derivatives of the S-Function
 */

static void mdlDerivatives(dx, x, u, S, tid)
    double *dx, *x, *u;
    SimStruct *S;
    int tid;
{
}

/*
 * mdlTerminate - called at termination of model execution.
 */

static void mdlTerminate(S)
    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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -