1

C を練習するための RLS フィルター用の MATLAB/mex コードを作成しようとしています。ただし、入力を使用して次のコードを実行しようとすると、セグメンテーション違反エラーが発生します。

#include <math.h>
#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{       
    /* Macros for input data */
    #define xData prhs[0] /* Input signal to filter */
    #define dData prhs[1] /* Desired output signal */
    #define deltaData prhs[2] /* For initializing covariance matrix */
    #define lambdaData prhs[3] /* Forgetting factor */
    #define MData prhs[4] /* Filter order */

    /* Macros for output data */
    #define wData plhs[0] /* Final filter coefficients */
    #define yData plhs[1] /* Filter output signal vector */
    #define eData plhs[2] /* Error vector */
    #define WData plhs[3] /* Filter coefficients matrix */

    /* Variables */
    mxArray *xT, *P, *q, *k; /* Temp arrays */
    double *xr, *xi, *dr, *di, delta, lambda;
    double *Pr, *Pi, *qr, *qi, *kr, *ki, *xTr, *xTi, den;
    double *wr, *wi, *yr, *yi, *er, *ei, *Wr, *Wi;
    int M, Mx, Md, Nx, Nd, m, n, m1, m2, nT, l;

    /* Get pointers to input data */
    xr = mxGetPr(xData); /* Real */
    xi = mxGetPi(xData); /* Imag */
    dr = mxGetPr(dData); /* Real */
    di = mxGetPi(dData); /* Imag */
    delta = mxGetScalar(deltaData);
    lambda = mxGetScalar(lambdaData);
    M = (int)mxGetScalar(MData);

    /* Get dimensions of input data */
    Mx = mxGetM(xData); /* Number of rows in x */
    Nx = mxGetN(xData); /* Number of columns in x */
    Md = mxGetM(dData); /* Number of rows in d */
    Nd = mxGetN(dData); /* Number of columns in d */

    /* Temporary vector - size M-by-1 */
    xT = mxCreateDoubleMatrix(M, 1, mxCOMPLEX);
    xTr = mxGetPr(xT); /* Real */
    xTi = mxGetPi(xT); /* Imag */

    /* Covariance matrix - size M-by-M */
    P = mxCreateDoubleMatrix(M, M, mxCOMPLEX);
    Pr = mxGetPr(P); /* Real */
    Pi = mxGetPi(P); /* Imag */

    /* Temporary vector for computing gain vector - size M-by-1 */
    q = mxCreateDoubleMatrix(M, 1, mxCOMPLEX);
    qr = mxGetPr(q); /* Real */
    qi = mxGetPi(q); /* Imag */

    /* Gain vector - size M-by-1 */
    k = mxCreateDoubleMatrix(M, 1, mxCOMPLEX);
    kr = mxGetPr(k); /* Real */
    ki = mxGetPi(k); /* Imag */

    /* Create output vector - size Mx-by-1 */
    yData = mxCreateDoubleMatrix(Mx, 1, mxCOMPLEX); 
    yr = mxGetPr(yData); /* Real */
    yi = mxGetPi(yData); /* Imag */

    /* Create error vector - size Mx-by-1 */
    eData = mxCreateDoubleMatrix(Mx, 1, mxCOMPLEX); 
    er = mxGetPr(eData); /* Real */
    ei = mxGetPi(eData); /* Imag */

    /* Create coeff. vector - size M-by-1 */
    wData = mxCreateDoubleMatrix(M, 1, mxCOMPLEX); 
    wr = mxGetPr(wData); /* Real */
    wi = mxGetPi(wData); /* Imag */

    /* Create coeff. matrix - size M-by-Mx */
    WData = mxCreateDoubleMatrix(M, Mx, mxCOMPLEX); 
    Wr = mxGetPr(WData); /* Real */
    Wi = mxGetPi(WData); /* Imag */

    m2 = 0;
    /* Initialize covariance matrix */
    for(m1 = 0; m1 < M; m1++, m2++)
    {
        Pr[m1*M+m2] = (1/delta); /* diag(P) = (1/delta) */
        Pi[m1*M+m2] = (1/delta); /* diag(P) = (1/delta) */
    }

    for(n = 0; n < Mx; n++)
    {
        /* Compute xT_m = [x[n] x[n-1] .... x[n-(M-1)]] */
        for(m = 0; m < M; m++)
        {/* Assume zeros outside available data and zero-fill*/
            if(n < (M-1)) 
            {
                nT = n;
                for(l = 0; l < M; l++)
                {
                     xTr[l] = xr[nT]; /* Real */
                     xTi[l] = xi[nT]; /* Imag */
                     if(nT == 0)
                         break;
                     else
                         nT--;
                 }
            } /* Data available for all lags */
            else 
            {   
                 xTr[m] = xr[n-m]; /* Real */
                 xTi[m] = xi[n-m]; /* Imag */
            }
            /* Set to zero prior to filling for computing gain vector */
            qr[m] = 0; /* Real */
            qi[m] = 0; /* Imag */
        }
    }
    return;
}

Atm エラーの原因を突き止めることができたので、大量のコードを切り取りました。以下のコードの次の部分をコメントアウトすると、実行されます(ただし、私には役に立ちません)。配列で使用されているインデックスを出力して、それらのいずれかが負になるかどうかを確認しようとしましたが、うまくいきませんでした。だから私は本当にエラーを見つけることができません。おそらくばかげた何かですが、エラーが何であるかを見つけることができません。以下の同じコード スニペットを別の関数 (LMS フィルター用) で使用したところ、正常に動作しました。2 つの関数の主な違いは、処理に必要な一時配列の量です。したがって、大きな問題は、セグメントにつながるコードの明らかな間違いに誰かが気付いているかということです。障害?(それ以外の場合、コードはおそらくできる限り良くないことを知っています。

for(m = 0; m < M; m++)
{/* Assume zeros outside available data and zero-fill*/
    if(n < (M-1)) 
    {
        nT = n;
        for(l = 0; l < M; l++)
        {
            // xTr[l] = xr[nT]; /* Real */
            // xTi[l] = xi[nT]; /* Imag */
            if(nT == 0)
                break;
            else
                nT--;
            }
    } /* Data available for all lags */
    else 
    {   
            // xTr[m] = xr[n-m]; /* Real */
            // xTi[m] = xi[n-m]; /* Imag */
    }
    /* Set to zero prior to filling for computing gain vector */
    qr[m] = 0; /* Real */
    qi[m] = 0; /* Imag */
}
4

1 に答える 1

1

ポインタがたくさんあるので、それらのいずれかがセグメンテーション違反を引き起こしている可能性があります。

あなたが行ったデバグから、おそらく問題は次のポインタの1つにあります。

xTr、xTi、xrまたはxi;

それらはすべて、関数mxGetPr()またはmxGetPi()で初期化されます。それが何をするのかを知らなければ、確信することは不可能です。配列へのポインタを返しますか?両方の配列に少なくともm個の要素がありますか?

そこにあるのは非常に複雑な構造なので、エラーを見つけるためにすべてのポインターを完全に分析するのは複雑な作業です。

于 2011-05-04T14:26:00.243 に答える