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

📄 vitcore.c

📁 Proakis《contemporarycommunication systems using matlab》matlab源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  P.S: This is a data processing function called by viterbi.m     */

/*-----------------------------------------------------------------------------
 *       Original Designed by Wes Wang
 *       Jun Wu        The MAthworks, Inc.
 *       Mar-3rd, 1996          
 *
 *       Copyright (c) 1996 by The MathWorks, Inc.
 *       All Rights Reserved
 *       $Revision: 1.1 $  $Date: 1996/04/01 18:14:52 $
 *-----------------------------------------------------------------------------
 */
#include <stdio.h>
#include <math.h>
#include "mex.h"

#include "vitlib.c"
#define Inf     mexGetInf()
#define one 1
/*
 * the main function
 */
void mexFunction(int nlhs, Matrix *plhs[], int nrhs, Matrix *prhs[])
{
  int    i, j, ii, jj, j2, j_k, j_pre, l, indx_j, num_N, num_K, NaN;
  int    n_code, m_code, colFunc, rowFunc, n_tran_prob, m_tran_prob, n_codd, n_msg, len_expen;
  int    N, M, K, num_state, n_std_sta, PowPowM, K2; 
  int    leng, len_C, len_pre_state, len_aft_state, len_plot_flag;
  int    expen_flag, trace_num, trace_eli, trace_pre, tran_indx, nex_sta_de, cur_sta_num;
  int    starter, dec, loc_tmp, numnotnan, loc_exp1, loca_exp1, tmp, lenIndx0, lenIndx1;
  double max, min, loca_exp, loc_exp;

  int    *A, *B, *C, *D, *expense1, *solution1, *solu, *sol1, *TRAN_A, *TRAN_B;  
  int    *inp_pre, *cur_sta_pre, *expen_work, *expen_tmp1, *pre_state, *cur_sta, *inp;
  int    *nex_sta, *out, *expenOut, *aft_state, *tmpIwork, *IWork; 
  double *code, *tran_func, *tran_prob, *Tran_prob, *plot_flag;
  double *msg, *expen, *codd;
  double *expense, *expen_tmp, *sol, *solution, *tmpRwork, *RWork;

  /*% routine check.
   *if nargin < 2
   *    error('Not enough input variable for VITERBI.');
   *elseif nargin < 3
   *    leng = 0;
   *end;
   *
   *% the case of unlimited delay and memory.
   *[n_code, m_code] = size(code);
   *if (leng <= 0) | (n_code <= leng)
   *    leng = n_code;
   *end;
   *if leng <= 1
   *    leng = 2;
   *end;
   *
   *if nargin < 4
   *    expen_flag = 0;     % expense_flag == 0 for BSC code;  == 1, with TRAN_PROB.
   *else
   *    [N, K] = size(tran_prob);
   *    if N < 3
   *        expen_flag = 0;
   *    else
   *        expen_flag = 1;
   *        expen_work = zeros(1, N); % work space.
   *        tran_prob(2:3, :) = log10(tran_prob(2:3, :));
   *    end;
   *end;
   *
   *if nargin < 5
   *    plot_flag(1) = 0;
   *else
   *    if (plot_flag(1) <= 0)
   *        plot_flag(1) = 0;
   *    elseif floor(plot_flag(1)) ~= plot_flag(1)
   *        plot_flag(1) = 0;
   *    end;
   *end;
   */

  /* deal properly with all kinds of input. */
  /* get the input(code, tran_func) of function */
  n_code = mxGetM(prhs[0]);
  m_code = mxGetN(prhs[0]);
  code = mxGetPr(prhs[0]);

  rowFunc = mxGetM(prhs[1]);
  colFunc = mxGetN(prhs[1]);
  tran_func = mxGetPr(prhs[1]);
  for(i=0; i < rowFunc*colFunc; i++){
    if( mxGetPr(prhs[1])[i] < 0 )
      tran_func[i] = -Inf;
  }

  if( tran_func[rowFunc*colFunc-1] == -Inf ){
    /* this kind of tran_func has A, B, C, D */ 
    N = (int)tran_func[ rowFunc*(colFunc-1) ];
    K = (int)tran_func[ rowFunc*(colFunc-1)+1 ];
    M = (int)tran_func[ rowFunc*(colFunc-1)+2 ];
    len_C = M*N;
  }else{
    /* this kind of tran_func is a two columns matrix */ 
    N = (int)tran_func[rowFunc];
    K = (int)tran_func[rowFunc+1];
    M = (int)tran_func[1];
    len_C = 0;
  }

  if(nrhs<3){
    leng = 0;
    expen_flag = 0;
    NaN = -1;
    len_plot_flag = 0;
  } else {
    leng = (int)mxGetPr(prhs[2])[0];  
    if( nrhs < 4 ){
      expen_flag = 0;
      NaN = -1;
      len_plot_flag = 0;
    } else {
      /* deal properly with all kinds of 'tran_prob' */
      n_tran_prob = mxGetM(prhs[3]);
      m_tran_prob = mxGetN(prhs[3]);
      Tran_prob = mxGetPr(prhs[3]);
      if(n_tran_prob < 3){
        expen_flag = 0;
        NaN = -1;
      }else{
        expen_flag = 1;
        NaN = 1;
        tran_prob = (double *)mxCalloc(m_tran_prob*n_tran_prob, sizeof(double));
        for(i=0; i < m_tran_prob; i++){
          tran_prob[i*n_tran_prob] = Tran_prob[i*n_tran_prob];
          tran_prob[i*n_tran_prob+1] = log10(Tran_prob[i*n_tran_prob+1]);
          tran_prob[i*n_tran_prob+2] = log10(Tran_prob[i*n_tran_prob+2]);
        }
      }

      /* deal properly with all kinds of 'plot_flag' */
      if( nrhs < 5 ){
        len_plot_flag = 0;
      }else{
        len_plot_flag = mxGetM(prhs[4])*mxGetN(prhs[4]);
        plot_flag = mxGetPr(prhs[4]);
        if( plot_flag[0] <= 0 )
          len_plot_flag = 0;
        else if ( (int)plot_flag[0] != plot_flag[0] )
          len_plot_flag = 0;
      }
    }
  }

  if( leng <= 0 || n_code <= leng )
    leng = n_code;
  if( leng <= 1 )
    leng = 2;
    
  /*if isstr(tran_func)
   *    tran_func = sim2tran(tran_func);
   *end;
   *% initial parameters.
   *[A, B, C, D, N, K, M] = gen2abcd(tran_func);
   */
  num_state = M;
  n_std_sta = 1;
  for(i=0; i < num_state; i++)
    n_std_sta = n_std_sta * 2;
  PowPowM = n_std_sta * n_std_sta;

  K2 = 1;
  for(i=0; i < K; i++)
    K2 = K2*2;

  if( expen_flag == 1 ){
    RWork =(double *)mxCalloc( (leng+4)*PowPowM+2*n_std_sta, sizeof(double));
                /* the number of real working space
                 * expense -------- leng*PowPowM
                 * solution ------- PowPowM
                 * sol ------------ PowPowM
                 * expen_tmp ------ PowPowM
                 * tmpRwork ------- 2*n_std_sta+PowPowM
                 */
    if( len_C != 0 )
      IWork =(int *)mxCalloc((M+N)*(M+K)+leng*PowPowM+K*(K2+1)+(4+M)*n_std_sta+3*N+2*M, sizeof(int));
                    /* A -------------- M*M
                     * B -------------- M*K
                     * C -------------- N*M
                     * D -------------- N*K
                     * solu ----------- leng*PowPowM
                     * inp_pre -------- K*K2
                     * cur_sta_pre ---- M*n_std_sta
                     * expen_work ----- N
                     * pre_state ------	n_std_sta
                     * cur_sta -------- M
                     * inp ------------ K
                     * nex_sta -------- M
                     * out ------------ N
                     * expenOut ------- N
                     * aft_state ------	n_std_sta
                     * tmpIwork ------- 2*n_std_sta
                     */
    else
      IWork = (int *)mxCalloc((rowFunc-2)*(M+N+2)+leng*PowPowM+K*(K2+1)+(4+M)*n_std_sta+3*N+2*M, sizeof(int));
                    /* TRAN_A --------- rowFunc-2
                     * TRAN_B --------- rowFunc-2
                     * A -------------- (rowFunc-2)*M
                     * B -------------- (rowFunc-2)*N
                     * same as above from *solu
                     */
  }else{
    /* no real working space */
    if( len_C != 0 )
      IWork =(int *)mxCalloc((M+N)*(M+K)+(2*leng+4)*PowPowM+K*(K2+1)+(6+M)*n_std_sta+2*N+2*M, sizeof(int));
                    /* A -------------- M*M
                     * B -------------- M*K
                     * C -------------- N*M
                     * D -------------- N*K
                     * expense1 ------- leng*PowPowM
                     * solution1 ------ PowPowM
                     * solu ----------- leng*PowPowM
                     * inp_pre -------- K*2^K
                     * cur_sta_pre ---- M*2^M
                     * pre_state ------	n_std_sta
                     * cur_sta -------- M
                     * inp ------------ K
                     * nex_sta -------- M
                     * out ------------ N
                     * expenOut ------- N
                     * aft_state ------	n_std_sta
                     * sol1 ----------- PowPowM
                     * expen_tmp1 ----- PowPowM
                     * tmpIwork ------- 4*n_std_sta+PowPowM
                     */
    else
      IWork = (int *)mxCalloc((rowFunc-2)*(M+N+2)+(2*leng+4)*PowPowM+K*(K2+1)+(6+M)*n_std_sta+2*N+2*M, sizeof(int));
                    /* TRAN_A --------- rowFunc-2
                     * TRAN_B --------- rowFunc-2
                     * A -------------- (rowFunc-2)*M
                     * B -------------- (rowFunc-2)*N
                     * same as above from *expense1
                     */
  }

  if( len_C != 0 ){
    A = IWork;
    B = A + M*M;
    C = B + M*K;
    D = C + M*N;
        
    /* 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)tran_func[i+j*(M+N)];
        if( i>M-1 && j<M )
          C[i+j*N-M] = (int)tran_func[i+j*(M+N)];
        if( i<M   && j>M-1 )
          B[i+j*M-M*M] = (int)tran_func[i+j*(M+N)];
        if( i>M-1 && j>M-1 )
          D[i+j*N-M*(N+1)] = (int)tran_func[i+j*(M+N)];
      }
    }
  }else{
    /* Assignment */
    TRAN_A = IWork;
    TRAN_B = TRAN_A + rowFunc-2;
    A = TRAN_B + rowFunc-2;
    B = A + M*(rowFunc-2);

    /* Get the input Matrix A, B */
    for(i=0; i < rowFunc-2; i++){
      TRAN_A[i] = (int)tran_func[i+2];
      TRAN_B[i] = (int)tran_func[rowFunc+i+2];
    }
    de2bi(TRAN_A, M, rowFunc-2, A);
    de2bi(TRAN_B, N, rowFunc-2, B);
  }
  /* end of Input Segment */

  if( expen_flag != 0 ){
    expense     = RWork;
    solution    = expense + leng*PowPowM;
    sol         = solution + PowPowM;
    expen_tmp   = sol + PowPowM;
    tmpRwork    = expen_tmp + PowPowM;

    if( len_C != 0 )
      solu = D + N*K;
    else
      solu = B + N*(rowFunc-2);

    inp_pre = solu + leng*PowPowM;        
    cur_sta_pre = inp_pre + K2*K;
    expen_work = cur_sta_pre + M*n_std_sta;
    pre_state = expen_work + N;
    cur_sta = pre_state + n_std_sta;
    inp = cur_sta + M;
    nex_sta = inp + K;
    out = nex_sta + M;
    expenOut = out + N;
    aft_state = expenOut + N;
    tmpIwork = aft_state + n_std_sta;
  }else{ /* tran_prob is not 3-row matrix */
    if( len_C != 0 )
      expense1 = D + N*K;
    else
      expense1 = B + N*(rowFunc-2);

    solu = expense1 + leng*PowPowM;    
    solution1 = solu + leng*PowPowM;
    inp_pre = solution1 + PowPowM;
    cur_sta_pre = inp_pre+ K2*K;
    pre_state =  cur_sta_pre + M*n_std_sta;
    cur_sta = pre_state + n_std_sta;
    inp = cur_sta + M;
    nex_sta = inp + K;
    out = nex_sta + M;
    expenOut = out + N;
    aft_state = expenOut + N;
    sol1 = aft_state + n_std_sta;
    expen_tmp1 = sol1 + PowPowM;
    tmpIwork = expen_tmp1 + PowPowM;
  }  

  /*if m_code ~= N
   *    if n_code == 1
   *        code = code';
   *        [n_code, m_code] = size(code);
   *    else
   *        error('CODE length does not match the TRAN_FUNC dimension in VITERBI.')
   *    end;
   *end;
   */

  if( m_code != N ){
    if(n_code == 1 ){
      n_code = m_code;
      m_code = 1;
	} else {
      mexErrMsgTxt("Code length does not match the TRAN_FUNC dimension in VITERBI.");
    }
  }

  /*% state size
   *if isempty(C)
   *    states = zeros(tran_func(2,1), 1);
   *else
   *    states = zeros(length(A), 1);
   *end;
   *num_state = length(states);
   */
  /* num_state has been set by the different TRAN_FUNC */

  /*% The STD state number reachiable is
   *n_std_sta = 2^num_state;
   *
   *PowPowM = n_std_sta^2;
   *
   *% at the very begining, the current state number is 1, only the complete zeros.
   *cur_sta_num = 1;
   *
   *% the variable expense is divided into n_std_sta section of size n_std_sta
   *% length vector for each row. expense(k, (i-1)*n_std_sta+j) is the expense of
   *% state j transfering to be state i
   *expense = ones(leng, PowPowM) * NaN;
   *expense(leng, [1:n_std_sta]) = zeros(1, n_std_sta);
   *solu = zeros(leng, PowPowM);
   *solution = expense(1,:);
   *
   *K2 = 2^K;
   */
  cur_sta_num = 1;  

⌨️ 快捷键说明

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