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

📄 apskdem3.c

📁 Proakis《contemporarycommunication systems using matlab》matlab源代码
💻 C
字号:
/*
 * APSKDEMO  ASK/PSK Demodulation phase detection and decision part
 *
 *           Syntax:  [sys, x0] = apskdemo(t,x,u,flag,M,Fc,N,P,R)
 *                      where M is the dimension of N and P.
 *                            N is the distribution of the centric circle.
 *                            P is the initial phase for each circle.
 *                            R is the assigned amplitude information.
 *                      there are three input:
 *                            u[0] is the modulated signal, block input.
 *                            u[1] is the tirgger signal which means the
 *                                  begining of the next input.
 * Wes Wang 5/2/94
 * Copyright (c) 1994-96 The MathWorks, Inc.
 * All Rights Reserved
 * $Revision: 1.1 $  $Date: 1996/04/01 19:01:34 $
 */

/* specify the name of this S-Function. */
#define S_FUNCTION_NAME apskdem3

/* Defines for easy access  the matrices which are passed in */
#define PI          3.14159265358979
#define NUM_ARGS    5
#define NUM_LAYER   ssGetArg(S, 0)
#define FRE_CARR  ssGetArg(S, 1)
#define NUM_IN_L  ssGetArg(S, 2)
#define PHA_IN_L  ssGetArg(S, 3)
#define AMP_IN_L  ssGetArg(S, 4)

/* include simstruc.h for the definition of the SimStruct and macro definitions. */
#include <math.h>
#ifdef MATLAB_MEX_FILE
#include <stdio.h>
#endif
#include "simstruc.h"

#ifdef MATLAB_MEX_FILE
#include "mex.h"
#endif

/*
 * mdlInitializeSizes - initialize the sizes array
 */

static void mdlInitializeSizes (S)
    SimStruct *S;
{
    if (ssGetNumArgs(S) == NUM_ARGS) {
      int    i, j, k, mulNum, idphNum, numInL;
        int    CurrentBase, numLayer;
           int    test;
            int    phaseIndex[256];
         double tmp, phases[256];   /* current maximum is 256 point */
           numLayer = mxGetPr(NUM_LAYER)[0];
       
#ifdef MATLAB_MEX_FILE
          if ((mxGetN(NUM_LAYER) != 1) || (mxGetM(NUM_LAYER) != 1)) {
         mexErrMsgTxt("The number of layer must be a scalar");
       }
       if ((mxGetN(FRE_CARR) != 1) || (mxGetM(FRE_CARR) != 1)) {
           mexErrMsgTxt("The carrier frequency must be a scalar");
     }
       if ((mxGetN(NUM_IN_L) * mxGetM(NUM_IN_L) != numLayer)) {
            mexErrMsgTxt("The vector size for number in each layer is not consistant");
         }
       if ((mxGetN(PHA_IN_L) * mxGetM(PHA_IN_L) != numLayer)) {
            mexErrMsgTxt("The vector size for initial phase in each layer is not consistant");
          }               
#endif

        /* block multiple number should be 2, 4, 8, 16, 32, 64, 128, or 256 */
        mulNum = 0;
        for (i = 0; i < numLayer; i++)
            mulNum += mxGetPr(NUM_IN_L)[i];

        /* number of independant phases */
        idphNum = -1;
        CurrentBase = 0;

        /* phaseIndex counted from the very out circle */
        for (i = numLayer-1; i >= 0; i--){
            if (i != numLayer - 1)
                CurrentBase += (int)mxGetPr(NUM_IN_L)[i+1];
            numInL = (int)mxGetPr(NUM_IN_L)[i];
            for (j = 0; j < numInL; j++) {
                tmp = mxGetPr(PHA_IN_L)[i] + ((double)(numInL - j - 1))*PI*2/numInL;
                k = 0; test = 1;

                while ((k <= idphNum) && test) {
                    if (fabs(tmp - phases[k]) <=0.00001) {
                        phaseIndex[CurrentBase + j] = k;
                        test = 0;
                    }
                    k++;
                }
                if (test) {
                    idphNum++;
                    phases[idphNum] = tmp;
                    phaseIndex[CurrentBase + j] = idphNum;
                }
            }
        }
        idphNum++;
        
        ssSetNumContStates(    S, idphNum); /* number of continuous states */
        ssSetNumDiscStates(    S, 0);       /* number of discrete states */
        ssSetNumInputs    (        S, 2);   /* number of inputs */
        ssSetNumOutputs   (        S, 1);   /* number of outputs */
        ssSetDirectFeedThrough(S, 0);       /* direct feedthrough flag */
        ssSetNumSampleTimes(   S, 1);       /* number of sample times */
        ssSetNumInputArgs(     S, NUM_ARGS);/* number of input arguments */
        /* last time of u[1]==1;
         * last calculated output;
         * independent number of state phase shift
         */
        ssSetNumRWork(         S, idphNum + 2);       /* number of real work vector elements */
        /* (1) state number
         * (2) real work vector
         * (3) point vector/ same as the multi number
         */
        ssSetNumIWork(         S, mulNum + 2);      /* number of integer work vector elements */
        ssSetNumPWork(         S, 0);      /* number of pointer work vector elements */
        } 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 - initialize the sample times array
 *
 * This function is used to specify the sample time(s) for your S-function.
 * If your S-function is continuous, you must specify a sample time of 0.0.
 * Sample times must be registered in ascending order.
 */

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

/*
 * mdlInitializeConditions - initialize the states
 * Initialize the states, Integers and real-numbers
 */

static void mdlInitializeConditions(double *x0, SimStruct *S)
{
        double *resetTime   = ssGetRWork(S);
        double *lastOut   = ssGetRWork(S) + 1;
        double *iniPhases = ssGetRWork(S) + 2;
        int    *staNum    = ssGetIWork(S);
        int    *mulNum    = ssGetIWork(S) + 1;
        int    *phaseInd  = ssGetIWork(S) + 2;

            int    i, j, k, mlNum, idphNum, test, CurrentBase, numLayer,numInL;
             double tmp, phases[256];   /* current maximum is 256 point */
           int    phaseIndex[256];

        /* multiple number */
            numLayer = mxGetPr(NUM_LAYER)[0];
        mlNum = 0;
        for (i = 0; i < numLayer; i++) {
            mlNum += (int)mxGetPr(NUM_IN_L)[i];
        }

        /* number of independant phases */
        idphNum = -1;
        CurrentBase = 0;
        /* phaseIndex counted from the very out circle */
        for (i = numLayer-1; i >= 0; i--){
            if (i != numLayer - 1)
                CurrentBase += (int)mxGetPr(NUM_IN_L)[i+1];
            numInL = (int)mxGetPr(NUM_IN_L)[i];
            for (j = 0; j < numInL; j++) {
                tmp = mxGetPr(PHA_IN_L)[i] + ((double)(numInL - j - 1))*PI*2/numInL;
                k = 0; test = 1;
                while ((k <= idphNum) && test) {
                    if (fabs(tmp - phases[k]) <=0.00001) {
                        phaseIndex[CurrentBase + j] = k;
                        test = 0;
                    }
                    k++;
                }
                if (test) {
                    idphNum++;
                    phases[idphNum] = tmp;
                    phaseIndex[CurrentBase + j] = idphNum;
                }
            }
        }
        idphNum++;
        
        *resetTime = 0;
        *lastOut = 0;
        for (i = 0; i < idphNum; i++) {
               *x0++ = 0.;
             *iniPhases++ = phases[i];
        }
        *staNum = idphNum;
        *mulNum = mlNum;
        for (i = 0; i < mlNum; i++)
            *phaseInd++ = phaseIndex[i];
}

/*
 * mdlOutputs - compute the outputs
 *
 * In this function, you compute the outputs of your S-function
 * block.  The outputs are placed in the y variable.
 */

static void mdlOutputs(y, x, u, S, tid)
    double *y, *x, *u;
    SimStruct *S;
    int tid;
{
    double *resetTime = ssGetRWork(S);
    double *lastOut   = ssGetRWork(S) + 1;
    double tmpTime;
    
    /* Time cumulated so far */
    tmpTime = ssGetT(S) - *resetTime;

    /* In the case of the output to be renewed */
    if ((u[1] != 0) && (tmpTime > 0)) {
        /* major computation */
        /* x[0] to x[staNum - 1] is the correlation result */

        int    *staNum    = ssGetIWork(S) ;        
        int    *mulNum    = ssGetIWork(S) + 1;
        int    *phaseInd  = ssGetIWork(S) + 2;
        double *iniPhase   = ssGetRWork(S) + 2;
        double mini, tmp, ampInL, submini, submaxi;
        int    i, j, decis, numBase, numInL, numLayer, decLay, subdecis, subsup;
        int    phaseIndex;              
        int    yesprint = 0;

        numLayer = mxGetPr(NUM_LAYER)[0];
        /* first find the best amplitude + phase match */
        numBase = 0;
        numInL = 0;
        for (i= numLayer-1; i>=0; i--) {
            numBase += numInL;
            numInL = (int)mxGetPr(NUM_IN_L)[i];
            ampInL = mxGetPr(AMP_IN_L)[i];
            submini = 10000000000.0;
            subdecis = numBase;
            submaxi = 0;
            subsup = numBase + 1;
            for (j=0; j<numInL; j++) {
                phaseIndex = *phaseInd;
                *phaseInd++;
#ifdef MATLAB_MEX_FILE
                if (yesprint) {
                        char   err_msg[256];
                    sprintf(err_msg, "phaseInd %d, staNum %d, i %d, j %d, numInL %d\n",
                     phaseIndex, *staNum, i, j, numInL);
                    mexPrintf(err_msg);
                }
#endif
                /* find the minimum */
                if (ampInL > 0)
                    tmp = fabs(x[phaseIndex] - ampInL * tmpTime / 2) / ampInL;
                else
                    tmp = fabs(x[phaseIndex] - ampInL * tmpTime / 2);                
                if (submini >= tmp) {
                    subdecis = *mulNum - numBase - j;
                    submini = tmp;
                }
                /* find the maximum */
                if (submaxi <= x[phaseIndex]) {
                    subsup = *mulNum - numBase - j;
                    submaxi = x[phaseIndex];
                }
#ifdef MATLAB_MEX_FILE
                if (yesprint) {
                        char   err_msg[256];                
                    sprintf(err_msg, "decision %d, mini %8.5f, tmp %8.5f, x[phaseInd] %8.5f, phaseInd %d, order %d, phase %6.3f\n",
                        decis, mini, tmp, x[phaseIndex], phaseIndex, numBase+j,iniPhase[phaseIndex]);
                    mexPrintf(err_msg);
                    sprintf(err_msg, "subdecis %d, submini %8.5f, subsup %d, submaxi %8.5f\n",
                        subdecis, submini, subsup, submaxi);
                    mexPrintf(err_msg);                    
                }
#endif
            }
            if (i == numLayer - 1) {
                mini = submini;
                decis = subdecis;
            } else if ((mini >= submini) && (subdecis == subsup)) {
                mini = submini;
                decis = subdecis;
            }
        }
        *lastOut = decis - 1;
        *resetTime = ssGetT(S);        
    }
    y[0] = *lastOut;
}


/*
 * mdlUpdate - perform action at major integration time step
 *
 * This function is called once for every major integration time step.
 * Discrete states are typically updated here, but this function is useful
 * for performing any tasks that should only take place once per integration
 * step.
 */

static void mdlUpdate(x, u, S, tid)
    double *x, *u;
    SimStruct *S;
    int tid;
{
    double *resetTime   = ssGetRWork(S);
    double CTime     = ssGetT(S);
    
    /* if input 3 is a nonzero value, reset the state of the integrator */
    if (*resetTime >= CTime) {
        int i;
        int    *staNum    = ssGetIWork(S);
        for (i = 0; i < *staNum; i++)
        x[i] = 0.0;
    }
}

/*
 * mdlDerivatives - compute the derivatives
 *
 * In this function, you compute the S-function block's derivatives.
 * The derivatives are placed in the dx variable.
 */

static void mdlDerivatives(dx, x, u, S, tid)
    double *dx, *x, *u;
    SimStruct *S;
    int tid;
{
    int    i;
    int    *staNum    = ssGetIWork(S);
    double *resetTime   = ssGetRWork(S);
    double *iniPhases = ssGetRWork(S) + 2;
    double CTime     = ssGetT(S);
    double fct;
    
    fct = (mxGetPr(FRE_CARR)[0]) * (CTime - *resetTime) * 2 * PI;
    for (i = 0; i < *staNum; i++) {
        dx[i] = sin(fct + iniPhases[i]) * u[0];
      }
}

/*
 * mdlTerminate - called when the simulation is terminated.
 *
 * In this function, you should perform any actions that are necessary
 * at the termination of a simulation.  For example, if memory was allocated
 * in mdlInitializeConditions, this is the place to free it.
 */

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