我已经将计算成本昂贵的Matlab代码部分转换为C mex文件,这大大加快了计算速度。问题是在某些运行中,C mex代码给出了与Matlab代码完全相同的结果(在机器精度范围内),而在其他一些代码中,两者之间存在显着差异(甚至达到1e-3)。此外,有时候C mex代码不同意它通过在完全相同的输入中连续运行不同的结果。我想这个问题可能是由于我编程导致的一些不正确的内存处理造成的。这很可能是我第一次尝试创建C mex文件。
我附加了我的mexFunction,它调用另一个C函数(在同一个文件中)来执行计算。如果你能给我一些关于我的问题的见解,我将不胜感激。如果您需要代码的任何其他部分,请告诉我。
提前致谢,
帕诺斯
void BladeElementGC(const mwIndex InterestBE, const mwIndex BladeElement,
const double *WakeXYZ, const double *RQuarter, const double *BE_RControl, const double *BE_Gamma,
const mwSize NoOfBlades, const mwSize NoOfFilaments, const mwSize NoOfSegments, const mwSize NoOfWakeItems,
const mwSize NoOfElements,
const double conf_CompressibleBiot, const double conf_M, const double conf_CompressibleWakeMachMax,
const double conf_VortexCoreOffset,
const double conf_VortexDelta,
const double conf_kin_visc,
const double conf_VatistasN,
const double conf_BoundVorticity,
double *GCBladeElement)
{
mwIndex Filament;
double Temp1[3], Temp2[3], Temp3[3];
GCBladeElement[0] = 0.;
GCBladeElement[1] = 0.;
GCBladeElement[2] = 0.;
Filament = BladeElement;
TrailingFilamentGC(InterestBE, Filament,
WakeXYZ, BE_RControl, BE_Gamma,
NoOfBlades, NoOfFilaments, NoOfSegments, NoOfWakeItems,
NoOfElements,
conf_CompressibleBiot, conf_M, conf_CompressibleWakeMachMax,
conf_VortexCoreOffset,
conf_VortexDelta,
conf_kin_visc,
conf_VatistasN,
Temp1);
TrailingFilamentGC(InterestBE, Filament+1,
WakeXYZ, BE_RControl, BE_Gamma,
NoOfBlades, NoOfFilaments, NoOfSegments, NoOfWakeItems,
NoOfElements,
conf_CompressibleBiot, conf_M, conf_CompressibleWakeMachMax,
conf_VortexCoreOffset,
conf_VortexDelta,
conf_kin_visc,
conf_VatistasN,
Temp2);
if (conf_BoundVorticity>0)
{
BoundElementGC(InterestBE, BladeElement,
WakeXYZ, RQuarter, BE_RControl, BE_Gamma,
NoOfBlades, NoOfFilaments, NoOfSegments, NoOfWakeItems,
NoOfElements,
conf_CompressibleBiot, conf_M, conf_CompressibleWakeMachMax,
conf_VortexCoreOffset,
conf_VortexDelta,
conf_kin_visc,
conf_VatistasN,
Temp3);
}
else
{
Temp3[0] = 0.;
Temp3[1] = 0.;
Temp3[2] = 0.;
}
GCBladeElement[0] = Temp2[0] - Temp1[0] + Temp3[0];
GCBladeElement[1] = Temp2[1] - Temp1[1] + Temp3[1];
GCBladeElement[2] = Temp2[2] - Temp1[2] + Temp3[2];
}
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
mwIndex InterestBE;
mwIndex BladeElement;
double *WakeXYZ;
double *RQuarter;
double *BE_RControl;
double *BE_Gamma;
double *GCBladeElement;
const mwSize *dimsWakeXYZ;
const mwSize *dimsBE_RControl;
mwSize NoOfBlades, NoOfFilaments, NoOfSegments, NoOfWakeItems;
mwSize NoOfElements, NoOfDimensions;
double p_CompressibleBiot;
double *p_M;
double *p_CompressibleWakeMachMax;
mwSize p_WakePointsNo;
double p_BoundVorticity;
double *p_VortexCoreOffset;
double *p_VortexDelta;
double *p_kin_visc;
double *p_VatistasN;
//----------------------------------------------------------
// First retrieve inputs
//----------------------------------------------------------
/* Get the value of the scalar input InterestBE */
InterestBE = (mwIndex)mxGetScalar(prhs[0]);
/* Get the value of the scalar input Filament */
BladeElement = (mwIndex)mxGetScalar(prhs[1]);
/* create a pointer to the real data in the WakeXYZ matrix */
WakeXYZ = mxGetPr(prhs[2]);
/* create a pointer to the real data in the RQuarter matrix */
RQuarter = mxGetPr(prhs[3]);
/* create a pointer to the real data in the BE_RControl matrix */
BE_RControl = mxGetPr(prhs[4]);
/* create a pointer to the real data in the BE_RControl matrix */
BE_Gamma = mxGetPr(prhs[5]);
/* create pointers to the fields of the conf structure */
p_CompressibleBiot = mxGetScalar(mxGetField(prhs[6], 0, "CompressibleBiot"));
p_M = mxGetPr(mxGetField(prhs[6], 0, "M"));
p_CompressibleWakeMachMax = mxGetPr(mxGetField(prhs[6], 0, "CompressibleWakeMachMax"));
p_VortexCoreOffset = mxGetPr(mxGetField(prhs[6], 0, "VortexCoreOffset"));
p_VortexDelta = mxGetPr(mxGetField(prhs[6], 0, "VortexDelta"));
p_kin_visc = mxGetPr(mxGetField(prhs[6], 0, "kin_visc"));
p_VatistasN = mxGetPr(mxGetField(prhs[6], 0, "VatistasN"));
p_WakePointsNo = (mwSize)mxGetScalar(mxGetField(prhs[6],0,"WakePoints"));
p_BoundVorticity = mxGetScalar(mxGetField(prhs[6],0,"BoundVorticity"));
// Get the dimensions of the WakeXYZ array
dimsWakeXYZ = mxGetDimensions(prhs[2]);
// Get the dimensions of the BE_RControl array
dimsBE_RControl = mxGetDimensions(prhs[4]);
NoOfBlades = dimsWakeXYZ[0];
NoOfFilaments = dimsWakeXYZ[1];
NoOfSegments = dimsWakeXYZ[2];
NoOfWakeItems = dimsWakeXYZ[3];
NoOfElements = dimsBE_RControl[1];
//----------------------------------------------------------
// Call the calculation subroutine
//----------------------------------------------------------
/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(1,3,mxREAL);
GCBladeElement = mxGetPr(plhs[0]);
BladeElementGC(InterestBE, BladeElement,
WakeXYZ, RQuarter, BE_RControl, BE_Gamma,
NoOfBlades, NoOfFilaments, NoOfSegments, NoOfWakeItems,
NoOfElements,
p_CompressibleBiot, *p_M, *p_CompressibleWakeMachMax,
*p_VortexCoreOffset,
*p_VortexDelta,
*p_kin_visc,
*p_VatistasN,
p_BoundVorticity,
GCBladeElement);
}