📄 vitcore.c
字号:
/* 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 + -