📄 sconvenc.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 2static 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 + -