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

📄 sconvenc.c

📁 Proakis《contemporarycommunication systems using matlab》matlab源代码
💻 C
字号:
/*============================================================================
 *  Syntax: [sys, x0, str, ts] = sconvenc(t, x, u, flag, tran_func);
 * SCONVENC SIMULINK file for convolution encoding.
 *   This file is designed to be used in a SIMULINK S-Function block.
 *   The function requires the system inputs
 *   tran_func  is one of the two forms of convolution code transfer function.
 *
 *=============================================================================
 *
 *     Original designed by Wes Wang,
 *     Jun Wu,     The Mathworks, Inc.
 *     Feb-07, 1996
 *
 *     Copyright (c) 1996 by The MAthWorks, Inc.
 *     All Rights Reserved
 *     $Revision: 1.1 $  $Date: 1996/04/01 19:04:10 $
 *=============================================================================
 */
#define S_FUNCTION_NAME sconvenc

#ifdef MATLAB_MEX_FILE
#include <stdio.h>
#endif
#include <math.h>

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

#define NUM_ARGS        1
#define TRAN_FUNC   ssGetArg(S,0)

#define Prim 2

static void de2bi(pde, dim, pow_dim, pbi)
     int *pde, dim, pow_dim, *pbi;
{
  int     i, j, tmp;

  for(i=0; i < pow_dim; i++){
    tmp = pde[i];
    for(j=0; j < dim; j++){
      pbi[i+j*pow_dim] = tmp % Prim;
      if(j < dim-1)
	tmp = (int)(tmp/Prim);
    }
  }
}

static void mdlInitializeSizes(S)
     SimStruct *S;
{
  int     i;
  int     N, M, K, colFunc, rowFunc;
  
  rowFunc = mxGetM(TRAN_FUNC);
  colFunc = mxGetN(TRAN_FUNC);
  
  if( mxGetPr(TRAN_FUNC)[rowFunc*colFunc-1] < 0 ){
    N = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)];
    K = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)+1];
    M = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)+2];
  }else{
    M = (int)mxGetPr(TRAN_FUNC)[1];
    N = (int)mxGetPr(TRAN_FUNC)[rowFunc];
    K = (int)mxGetPr(TRAN_FUNC)[rowFunc+1];
  }
  
  ssSetNumContStates(     S, 0);          /* number of continuous states */
  ssSetNumDiscStates(     S, M);          /* number of discrete states */
  ssSetNumOutputs(        S, N);          /* number of outputs */
  ssSetNumInputs(         S, K+1);        /* number of inputs */
  ssSetDirectFeedThrough( S, 0);          /* direct feedthrough flag */
  ssSetNumSampleTimes(    S, 1);          /* number of sample times */
  ssSetNumInputArgs(      S, NUM_ARGS);   /* number of input arguments */
  ssSetNumRWork(          S, 0);          /* number of real working space */
  if( mxGetPr(TRAN_FUNC)[rowFunc*colFunc-1] < 0 )
    ssSetNumIWork( S,  (M+N)*(M+K)+M);
  /* A -------------- M*M
   * B -------------- M*K
   * C -------------- N*M
   * D -------------- N*K
   * tmpRoom -------- M
   */
  else
    ssSetNumIWork( S, (rowFunc-2)*(M+N+2));
  /* TRAN_A --------- rowFunc-2
   * TRAN_B --------- rowFunc-2
   * A -------------- (rowFunc-2)*M
   * B -------------- (rowFunc-2)*N
   */
  ssSetNumPWork(          S, 0);
}

/*
 * mdlInitializeConditions - initialize the states
 * Initialize the states, Integers and real-numbers
 */
static void mdlInitializeConditions(x0, S)
     double *x0;
     SimStruct *S;
{
/*elseif flag == 0
 *  [A, B, C, D, N, K, M] = gen2abcd(tran_func);
 *  x0 = zeros(M, 1);
 *  sys = [0; length(x0); N; K+1; 0; 0; 1];
 *  ts = [-1, 0];
 *else
 *  sys = [];
 *end;
 */
  int     i, j, len_C;
  int     N, M, K, colFunc, rowFunc;
  int     *TRAN_A, *TRAN_B;
  int     *A, *B, *C, *D, *tmpRoom;
  
  colFunc = mxGetN(TRAN_FUNC);
  rowFunc = mxGetM(TRAN_FUNC);
  
  if( mxGetPr(TRAN_FUNC)[rowFunc*colFunc-1] < 0 ){
    N = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)];
    K = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)+1];
    M = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)+2];
    len_C = M*N;
    
    A = ssGetIWork(S);
    B = A + M*M;
    C = B + M*K;
    D = C + N*M;
    tmpRoom = D + N*K;
    for(i=0; i < M; i++){
      x0[i] = 0;
      tmpRoom[i] = (int)x0[i];
    }
    
  }else{
    N = (int)mxGetPr(TRAN_FUNC)[rowFunc];
    K = (int)mxGetPr(TRAN_FUNC)[rowFunc+1];
    M = (int)mxGetPr(TRAN_FUNC)[1];
    len_C = 0;
    
    /* Assignment */
    TRAN_A =    ssGetIWork(S);/*   !--- size of *TRAN_A */
    TRAN_B =    ssGetIWork(S) + (rowFunc-2);/* <--- size of *TRAN_B */
    A =         ssGetIWork(S) + 2*(rowFunc-2);/*    !----- size of *A */ 
    B =         ssGetIWork(S) + 2*(rowFunc-2) + (rowFunc-2)*M;/*    !----- size of *B */
    /* Get the input Matrix A, B */
    for(i=0; i < rowFunc-2; i++){
      TRAN_A[i] = (int)mxGetPr(TRAN_FUNC)[i+2];
      TRAN_B[i] = (int)mxGetPr(TRAN_FUNC)[rowFunc+i+2];
    }
    de2bi(TRAN_A, M, rowFunc-2, A);
    de2bi(TRAN_B, N, rowFunc-2, B);
    for(i=0; i < M; i++)
      x0[i] = 0;
  }
}

/*
 * 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);
}

/*
 * 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;
{
/*elseif flag == 3 % output
 *  if u(length(u)) < .2
 *    % in the case of no signal, no processing.
 *    return;
 *  end;
 *  % otherwise, there is a signal, have to process.
 *  % initial parameters.
 *  [A, B, C, D, N, K, M] = gen2abcd(tran_func);
 *  u = u(1:K);
 *  if isempty(C)
 *    msg_i = bi2de(u(:)');
 *%    tran_indx = x(1) + 1 + msg_i * 2^K;
 *    tran_indx = x(1) + 1 + msg_i * 2^M;
 *    sys = B(tran_indx, :)';
 *  else
 *    x = x(:); u = u(:);
 *    sys = C * x + D * u;
 *    sys = rem(sys, 2);
 *  end;
 */
  int     i, j, len_C, msg_i, tran_indx, sum, tmp;
  int     colFunc, rowFunc, M, K, N, n_std_sta;
  int     *TRAN_A, *TRAN_B;
  int     *A, *B, *C, *D, *tmpRoom;
  
  rowFunc = mxGetM(TRAN_FUNC);
  colFunc = mxGetN(TRAN_FUNC);
  
  if( mxGetPr(TRAN_FUNC)[rowFunc*colFunc-1] < 0 ){
    N = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)];
    K = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)+1];
    M = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)+2];
    len_C = M*N;
    
    A = ssGetIWork(S);
    B = A + M*M;
    C = B + M*K;
    D = C + N*M;
    tmpRoom = D + N*K;
    for(i=0; i < M; i++)
      tmpRoom[i] = (int)x[i];
    
    /* Get the input Matrix A, B, C, D */
    for( i=0; i < M+N; i++ ){
      for( j=0; j < M+K; j++ ){
	if( i<M   && j<M )
	  A[i+j*M] = (int)mxGetPr(TRAN_FUNC)[i+j*(M+N)];
	if( i>M-1 && j<M )
	  C[i+j*N-M] = (int)mxGetPr(TRAN_FUNC)[i+j*(M+N)];
	if( i<M   && j>M-1 )
	  B[i+j*M-M*M] = (int)mxGetPr(TRAN_FUNC)[i+j*(M+N)];
	if( i>M-1 && j>M-1 )
	  D[i+j*N-M*(N+1)] = (int)mxGetPr(TRAN_FUNC)[i+j*(M+N)];
      }
    }
  }else{
    N = (int)mxGetPr(TRAN_FUNC)[rowFunc];
    K = (int)mxGetPr(TRAN_FUNC)[rowFunc+1];
    M = (int)mxGetPr(TRAN_FUNC)[1];
    len_C = 0;
    
    /* Assignment */
    TRAN_A =    ssGetIWork(S);/*   !--- size of *TRAN_A */
    TRAN_B =    ssGetIWork(S) + (rowFunc-2);/* <--- size of *TRAN_B */
    A =         ssGetIWork(S) + 2*(rowFunc-2);/*    !----- size of *A */ 
    B =         ssGetIWork(S) + 2*(rowFunc-2) + (rowFunc-2)*M;/*    !----- size of *B */
    
    /* Get the input Matrix A, B */
    for(i=0; i < rowFunc-2; i++){
      TRAN_A[i] = (int)mxGetPr(TRAN_FUNC)[i+2];
      TRAN_B[i] = (int)mxGetPr(TRAN_FUNC)[rowFunc+i+2];
    }
    de2bi(TRAN_A, M, rowFunc-2, A);
    de2bi(TRAN_B, N, rowFunc-2, B);
  }
  
  n_std_sta = 1;
  for(i=0; i < M; i++)
    n_std_sta = n_std_sta * 2;
  
  if( u[K] >= 0.2 ){
    if( len_C == 0 ){
      msg_i = 0;
      for (i=0; i < K; i++){
       	tmp = (int)u[i];
    	if ( tmp != 0 && i > 0 ){
    	  for (j=0; j < i; j++)
    	    tmp = tmp*2;
    	}
    	msg_i = msg_i + tmp;
      }
      tran_indx = (int)x[0] +1 + msg_i * n_std_sta;
      for(i=0; i < N; i++)
    	y[i] = (double)B[tran_indx-1+i*(rowFunc-2)];
    }else{
      for(i=0; i < N; i++){
    	sum = 0;
    	for(j=0; j < M; j++)
    	  sum = sum + C[i+j*N]*tmpRoom[j];
    	for(j=0; j < K; j++)
    	  sum = sum + D[i+j*N]*u[j];
    	y[i] = (double)(sum % 2);
      }
    }
  }
}

/*
 * 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. PS: flag = 2.
 */
static void mdlUpdate(x, u, S, tid)
     double *x, *u; 
     SimStruct *S; 
     int tid;
{
  /*
   *if (flag == 2) % refresh discrete-time states
   *  % the major processing routine.
   *  if u(length(u)) < .2
   *    % in the case of no signal, no processing.
   *    return;
   *  end;
   *
   *  % otherwise, there is a signal, have to process.
   *
   *  % initial parameters.
   *  [A, B, C, D, N, K, M] = gen2abcd(tran_func);
   *  u = u(1:K);
   *  if isempty(C)
   *    sys = zeros(M, 1);
   *    msg_i = bi2de(u(:)');
   *    tran_indx = x(1) + 1 + msg_i * 2^M;
   *    sys(1) = tran_func(tran_indx+2, 1);
   *  else
   *    x = x(:); u = u(:);
   *    sys = A * x + B * u;
   *    sys = rem(sys, 2);
   *  end;
   */    
  int     i, j, sum, len_C, msg_i, tran_indx, tmp;
  int     colFunc, rowFunc, M, K, N, n_std_sta;
  int     *TRAN_A, *TRAN_B;
  int     *A, *B, *C, *D, *tmpRoom;
  
  rowFunc = mxGetM(TRAN_FUNC);
  colFunc = mxGetN(TRAN_FUNC);
  
  if( mxGetPr(TRAN_FUNC)[rowFunc*colFunc-1] < 0 ){
    N = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)];
    K = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)+1];
    M = (int)mxGetPr(TRAN_FUNC)[rowFunc*(colFunc-1)+2];
    len_C = M*N;
    
    A = ssGetIWork(S);
    B = A + M*M;
    C = B + M*K;
    D = C + N*M;
    tmpRoom = D + N*K;
    for(i=0; i < M; i++)
      tmpRoom[i] = (int)x[i];
    
    /* Get the input Matrix A, B, C, D */
    for( i=0; i < M+N; i++ ){
      for( j=0; j < M+K; j++ ){
	if( i<M   && j<M )
	  A[i+j*M] = (int)mxGetPr(TRAN_FUNC)[i+j*(M+N)];
	if( i>M-1 && j<M )
	  C[i+j*N-M] = (int)mxGetPr(TRAN_FUNC)[i+j*(M+N)];
	if( i<M   && j>M-1 )
	  B[i+j*M-M*M] = (int)mxGetPr(TRAN_FUNC)[i+j*(M+N)];
	if( i>M-1 && j>M-1 )
	  D[i+j*N-M*(N+1)] = (int)mxGetPr(TRAN_FUNC)[i+j*(M+N)];
      }
    }
  }else{
    N = (int)mxGetPr(TRAN_FUNC)[rowFunc];
    K = (int)mxGetPr(TRAN_FUNC)[rowFunc+1];
    M = (int)mxGetPr(TRAN_FUNC)[1];
    len_C = 0;
  }
  
  n_std_sta = 1;
  for(i=0; i < M; i++)
    n_std_sta = n_std_sta * 2;
  
  if ( u[K] >= 0.2 ){
    if( len_C == 0 ){
      msg_i = 0;    
      for (i=0; i < K; i++){
	tmp = (int)u[i];
	if ( u[i] != 0 && i > 0 ){
	  for (j=0; j < i; j++)
	    tmp = tmp*2;
	}
	msg_i = msg_i + tmp;
      }
      tran_indx = (int)x[0] + 1 + msg_i * n_std_sta;
      x[0] = mxGetPr(TRAN_FUNC)[tran_indx+1];
    }else{
      for(i=0; i < M; i++){
	sum = 0;
	for(j=0; j < M; j++)
	  sum = sum + A[i+j*M]*tmpRoom[j];
	for(j=0; j < K; j++)
	  sum = sum + B[i+j*M]*u[j];
	x[i] = (double)(sum % 2);
      }
    }
  }
}
/*
 * 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;
{
}

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