【问题标题】:Run Matlab mex-Algorithm instead of Double- in Single-Precision运行 Matlab mex-Algorithm 而不是 Double- in Single-Precision
【发布时间】:2011-09-20 18:02:47
【问题描述】:

我有一个当前使用双精度的工作 Matlab C 代码(mex 文件)。因此我替换了

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

mxCreateDoubleMatrixmxCreateNumericArray()

double 变量 float 的数据类型。唯一正在使用的其他 mex-Function 是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 使用双精度时,相同的代码运行良好。我还尝试通过 point = zeros(rows, 1, 'single'); 显式传递点来调用 mex-Function。

非常感谢您指出正确的方向或给我任何提示。谢谢!

【问题讨论】:

    标签: matlab precision infinite-loop mex


    【解决方案1】:

    您需要将abs() 替换为fabs()

    一般来说,在这种情况下,我会使用mexPrintf() 来打印影响终止条件的值。即,如果上述更改没有帮助,请尝试添加

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

    只是为了确保行为符合您的预期。

    【讨论】:

    • 非常感谢,这真的可以帮助我。我稍后会尝试并告诉你它是否有效。
    • 啊,还有一个问题:mxArray *newPnt = mxDuplicateArray(prhs[0]); 会做什么?即使在通过myMexFunc(ones(1000, 1)) 调用 mex-Function 时使用float *newPntDat = (float*)mxGetData(newPnt); 也能工作,还是我必须将参数“single”指定给 one()?
    • 您仍然必须使用 'single' 参数。否则,默认情况下传递给 mex 的数组将是双精度的,并且您不能将其强制转换为浮点数(mxDuplicateArray 会以任何一种方式工作——结果与输入的类型相同,并且仅当您传递单精度数组时才会是单数组到墨西哥)
    • 好的,再次感谢 - 我也是这么想的 :) 我试过了,但不知何故,当把它转移到使用浮点数时,算法不起作用......问题:因为 H 和 @987654329 @ 是输入参数(我将其转换为浮点数)并用于中止条件if(abs(df2-df1) &lt;= diff) 我是否还需要以某种方式将它们作为“单个”值传递?目前我只是在使用类似myMexFunc(ones(100, 1, 'single'), 0.001, 0.0001)...
    • 编辑:也试过了,但还是不行。所以我必须通过许多调试输出进一步研究它......可能你不能帮助更多的代码吧?
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2014-09-30
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 2012-12-17
    相关资源
    最近更新 更多