Запустите мекс-алгоритм Matlab вместо двойной точности одинарной точности - PullRequest
0 голосов
/ 23 июня 2011

У меня есть рабочий код Matlab C (mex файлы), который в настоящее время использует двойную точность. Таким образом я заменил

double *datOut = mxGetPr(mxOut) по float *datOut = (float*)mxGetData(mxOut);,

mxCreateDoubleMatrix по mxCreateNumericArray()

и

типы данных переменных double от float. Единственная другая мекс-функция, которая используется, это mxDuplicateArray(), но не более того. Я ничего не изменил в этом вызове ... Теперь у меня работает код, который никогда не заканчивается. Я немного его урезал, так что надеюсь, что он достаточно короткий, чтобы кто-нибудь мог мне помочь:

float myFunc(const mxArray *point, int index)
{
    float *dat = (float*)mxGetData(point);
    return dat[index]*dat[index]*dat[index];
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
    float h, f0, df1, df2, diff;

    // Input Vars #1
    float diff  = (float)mxGetScalar(prhs[1]);
    float H = (float)mxGetScalar(prhs[2]);
    int index1 = (int)mxGetScalar(prhs[3]);
    int index2 = (int)mxGetScalar(prhs[4]);

    // Input Vars #2 -> Duplicate it
    mxArray *newPnt = mxDuplicateArray(prhs[0]);
    float *newPntDat = (float*)mxGetData(newPnt);

    // ...
    // PERHAPS SOME UNIMPORANT CODE HERE ...
    // ...
    h = H;
    f0 = myFunc(prhs[0], index1);

    newPntData[ index2 ] += h;
    df1 = (myFunc(newPnt, index1)-f0)/h;
    while(true)
    {
        h /= 2;

        newPntDat[ index2 ] -= h;
        df2 = (myFunc(newPnt, index1)-f0)/h;

        // If precision is okay
        if(abs(df2-df1) <= diff)
            break;

        // Save for next loop iteration
        df1 = df2;
    }

    // Return df2-Value to Matlab
}

каким-то образом это бесконечный цикл, и я не знаю, почему, поскольку точность, определяемая с помощью diff, должна быть легко достижимой для данной функции myFunc(). Идентичный код работает нормально при использовании двойной точности с обеими функциями double *datOut = mxGetPr(mxOut) и mxCreateDoubleMatrix. Я также пытался вызвать mex-функцию, явно передав точку через point = zeros(rows, 1, 'single');.

Большое спасибо за то, что указали мне правильное направление или дали ЛЮБОЙ намек на это. Спасибо!

1 Ответ

1 голос
/ 23 июня 2011

Вам необходимо заменить abs() на fabs().

Как правило, в таких случаях я бы использовал mexPrintf() для печати значений, которые влияют на условие завершения.Т.е., если указанное выше изменение не помогает, попробуйте добавить

mexPrintf("%g %g %g %g\n",df2,df1,diff, fabs(df2-df1));

, чтобы убедиться, что поведение соответствует ожидаемому.

...