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

📄 cmplxflt.c

📁 Proakis《contemporarycommunication systems using matlab》matlab源代码
💻 C
字号:
/*
 * SCHDINT   A SIMULINK scheduling integration
 *
 *           Syntax:  [sys, x0] = cmplxflt(t, x, u, flag, NUM, DEN, TS)
 *
 *      This block will reset the integration to be zero at K*TD(1) + TD(2).
 *      TS: sampling time of the integration. This is a discrete-time block.
 *      Modulo: Limitation of the integration. When State is larger than this
 *              value it will do x=rem(x,Modulo) computation.
 *
 * Wes Wang Dec. 8, 1994
 * Copyright (c) 1994-96 by The MathWorks, Inc.
 * All Rights Reserved
 * $Revision: 1.1 $  $Date: 1996/04/01 19:02:34 $
 */

#define S_FUNCTION_NAME cmplxflt

#include <math.h>     /* needed for declaration of sprintf */

#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   3
#define NUM        ssGetArg(S,0)
#define DEN        ssGetArg(S,1)
#define TS         ssGetArg(S,2)

/*
 * 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  den_length, num_length;

       num_length = mxGetN(NUM) - 1;
       den_length = mxGetN(DEN) - 1;
/*
#ifdef MATLAB_MEX_FILE
    if (1) {
        char err_msg[256];
        sprintf(err_msg, "num_length= %d, den_length = %d\n",num_length, den_length);
        mexPrintf(err_msg);
    }
#endif
 */     
       if (mxGetM(NUM) > 2) {
#ifdef MATLAB_MEX_FILE
           mexErrMsgTxt("The row number of the numerator cannot be larger than 2.");
#endif
       }
       if (mxGetM(DEN) > 2) {
#ifdef MATLAB_MEX_FILE
           mexErrMsgTxt("The row number of the denominator cannot be larger than 2.");
#endif
       }
       if ((mxGetN(TS)*mxGetM(TS) != 1) &&
           (mxGetN(TS)*mxGetM(TS) != 2)) {
#ifdef MATLAB_MEX_FILE
           mexErrMsgTxt("The sample time must be a scalar or a vector of length 2");
#endif
       }
       if ((mxGetN(NUM)*mxGetM(NUM) <=0) ||
           (mxGetN(DEN)*mxGetM(DEN) <=0)) {
#ifdef MATLAB_MEX_FILE
           mexErrMsgTxt("The numerator or the denominator is empty.");
#endif
       }
       ssSetNumContStates(    S, 0);
       ssSetNumDiscStates(    S, num_length*2+den_length*2);
       ssSetNumInputs(        S, -1);
       ssSetNumOutputs(       S, 2);
       if (mxGetM(NUM) > 1) {
          if ((mxGetPr(NUM)[0] == 0.0) && (mxGetPr(NUM)[1] == 0.0))
            ssSetDirectFeedThrough(S, 0);
          else
            ssSetDirectFeedThrough(S, 1);
       } else {
          if (mxGetPr(NUM)[0] == 0.0)
            ssSetDirectFeedThrough(S, 0);
          else
            ssSetDirectFeedThrough(S, 1);
       }
       ssSetNumInputArgs(     S, NUM_ARGS);
       ssSetNumSampleTimes(   S, 1);
       ssSetNumRWork(         S, 4);
       ssSetNumIWork(         S, 1);
       ssSetNumPWork(         S, 0);
    } 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(TS)[0];
    if ((mxGetN(TS) * mxGetM(TS)) == 2)
       offsetTime = mxGetPr(TS)[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;
{
    double *x2_y2  = ssGetRWork(S);
    double *lastTime        = ssGetRWork(S) + 1;
    double *lastY           = ssGetRWork(S) + 2;
    int    *lastCalculation = ssGetIWork(S);    

    int in_row = ssGetNumInputs(S);
    int num_length = mxGetN(NUM) - 1;
    int den_length = mxGetN(DEN) - 1;

    int i;

    if (in_row > 2) {
#ifdef MATLAB_MEX_FILE
        mexErrMsgTxt("The input vector length must be less than 2.");
#endif
    }    

    if (ssGetT(S) <= 0) {
        for (i = 0; i < 2*(num_length+den_length); i++)
            x0[i] = 0.0;
    }
    if (mxGetM(DEN) > 1) {
        if ((mxGetPr(DEN)[0] == 0.0) && (mxGetPr(DEN)[1] == 0.0)) {
#ifdef MATLAB_MEX_FILE
            mexErrMsgTxt("The first column of the denominator cannot be zero.");
#endif
		} else {
		    *x2_y2 = mxGetPr(DEN)[0] * mxGetPr(DEN)[0] + mxGetPr(DEN)[1] * mxGetPr(DEN)[1];
		}
	} else {
        if (mxGetPr(DEN)[0] == 0.0) {	    
#ifdef MATLAB_MEX_FILE
        mexErrMsgTxt("The first element of the denominator cannot be zero.");
#endif
		} else {
		    *x2_y2 = mxGetPr(DEN)[0] * mxGetPr(DEN)[0];		    
		}
    }
    lastTime[0] = -1;
    lastY[0] = 0;
    lastY[1] = 0;
    lastCalculation = 0;
}

/* routine called by both mdlOutputs and mdlUpdate */
static void ComplexFilterUpdate(y, x, u, S)
    double *y, *x, *u;
    SimStruct *S;
{
    double *x2_y2  = ssGetRWork(S);    
    double *num    = mxGetPr(NUM);
    double *den    = mxGetPr(DEN);

    int in_row     = ssGetNumInputs(S);
    int num_length = mxGetN(NUM) - 1;
    int num_row    = mxGetM(NUM);
    int den_length = mxGetN(DEN) - 1;
    int den_row    = mxGetM(DEN);

    
    int i, j;

    double tmp;

    if ((in_row > 1) && (num_row > 1)) {
        y[0] = u[0] * num[0] - u[1] * num[1];
        y[1] = u[0] * num[1] + u[1] * num[0];
    } else if ((in_row <= 1) && (num_row > 1)) {
        y[0] = u[0] * num[0];
        y[1] = u[0] * num[1];
    } else if ((in_row > 1) && (num_row <= 1)) {
        y[0] = u[0] * num[0];        
        y[1] = u[1] * num[0];        
    } else {
        y[0] = u[0] * num[0];
        y[1] = 0;
    }
    if (num_row > 1) {
        /* cmplex num */        
        i = 0;
        while (i < num_length) {
             y[0] = y[0]
                    + x[(den_length+i)*2] * num[i*2+2]
                    - x[(den_length+i)*2+1] * num[i*2+3];
             y[1] = y[1]
                    + x[(den_length+i)*2] * num[i*2+3]
                    + x[(den_length+i)*2+1] * num[i*2+2];
             i++;
        }
    } else {
        /* real num */
        i = 0;
        while (i < num_length) {
             y[0] = y[0]
                    + x[(den_length+i)*2] * num[i+1];
             y[1] = y[1]
                    + x[(den_length+i)*2+1] * num[i+1];
             i++;
		}
	}
    if (den_row > 1) {
        /* cmplex den */
        i = 0;
        while (i < den_length) {
             y[0] = y[0]
                    - x[i*2] * den[i*2+2]
                    + x[i*2+1] * den[i*2+3];
             y[1] = y[1]
                    - x[i*2] * den[i*2+3]
                    - x[i*2+1] * den[i*2+2];
             i++;
        }
    	tmp = y[0] * den[0] + y[1] * den[1];
		y[1] = - y[0] * den[1] + y[1] * den[0];
		y[0] = tmp / x2_y2[0];
		y[1] = y[1] / x2_y2[0];			
    } else {
        /* real den */
        i = 0;
        while (i < den_length) {
             y[0] = y[0]
                    - x[i*2] * den[i + 1];
             y[1] = y[1]
                    - x[i*2+1] * den[i + 1];
             i++;
		}
        y[0] = y[0] / den[0];
		y[1] = y[1] / den[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;
{
    double *lastTime        = ssGetRWork(S) + 1;
    double *lastY           = ssGetRWork(S) + 2;
    int    *lastCalculation = ssGetIWork(S);

    /*
#ifdef MATLAB_MEX_FILE
    if (1) {
        char err_msg[256];
        sprintf(err_msg, "In Yout Time= %f, lastTime= %f, lastCal = %d   ",ssGetT(S), lastTime[0], lastCalculation[0]);
        mexPrintf(err_msg);
    }
#endif
    */   
    if ((ssGetT(S) > lastTime[0]) || (lastCalculation[0] == 1)) {
        /*
#ifdef MATLAB_MEX_FILE
        if (1) {
            char err_msg[256];
            sprintf(err_msg, "Update\n");
            mexPrintf(err_msg);
        }
#endif
        */
        /* need new calculation */
        ComplexFilterUpdate(y, x, u, S);
        lastTime[0] = ssGetT(S);
        lastCalculation[0] = 1;
        lastY[0] = y[0];
        lastY[1] = y[1];
    } else {
        /*
#ifdef MATLAB_MEX_FILE
        if (1) {
            char err_msg[256];
            sprintf(err_msg, "No-Update\n");
            mexPrintf(err_msg);
        }
#endif
        */
        /* take the storage data */
        y[0] = lastY[0];
        y[1] = lastY[1];
    }
}

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

static void mdlUpdate(x, u, S, tid)
    double *x, *u;
    SimStruct *S;
    int tid;
{
    double *lastTime        = ssGetRWork(S) + 1;
    double *lastY           = ssGetRWork(S) + 2;
    int    *lastCalculation = ssGetIWork(S);    
    int in_row     = ssGetNumInputs(S);
    int num_length = mxGetN(NUM) - 1;
    int den_length = mxGetN(DEN) - 1;
    
    int i, j;

    double y[2];
    /*
#ifdef MATLAB_MEX_FILE
    if (1) {
        char err_msg[256];
        sprintf(err_msg, "In Xupdate Time= %f, lastTime= %f, lastCal = %d    ",ssGetT(S), lastTime[0], lastCalculation[0]);
        mexPrintf(err_msg);
    }
#endif
    */
    if ((ssGetT(S) > lastTime[0]) || (lastCalculation[0] == 0)) {
        /*
#ifdef MATLAB_MEX_FILE
        if (1) {
            char err_msg[256];
            sprintf(err_msg, "Update\n");
            mexPrintf(err_msg);
        }
#endif
        */
        /* need new calculation */
        ComplexFilterUpdate(y, x, u, S);
        lastTime[0] = ssGetT(S);
        lastCalculation[0] = 0;
        lastY[0] = y[0];
        lastY[1] = y[1];
    } else {
        /*
#ifdef MATLAB_MEX_FILE
        if (1) {
            char err_msg[256];
            sprintf(err_msg, "No-Update\n");
            mexPrintf(err_msg);
        }
#endif
        */
        /* take the storage data */
        y[0] = lastY[0];
        y[1] = lastY[1];
    }
    
    for (i = den_length+num_length-1; i > 0 ; i--) {
        x[i*2 + 1] = x[i*2 - 1];
        x[i*2] = x[i*2 - 2];
    }
    if (den_length > 0) {    
        x[0] = y[0];
        x[1] = y[1];
    }
    if (num_length > 0) {
        x[2*den_length] = u[0];
        if (in_row > 1)
           x[2*den_length+1] = u[1];
        else
           x[2*den_length+1] = 0;
    }
}

/*
 * 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 + -