主要内容

升级MEX文件以使用交错复杂API

本主题介绍如何升级MEX文件以使用交错复杂API。您可以通过调用来继续使用单独的复杂API梅克斯命令-R2017b选择。但是,有关使用此选项的更多信息,请参见我是否需要升级MEX文件以使用交错的复杂API?

请注意

如果您使用的是使用MEX文件梅克斯命令-compatibleArrayDims选项,则必须首先更新源代码以使用64位API。信息,请参阅升级MEX文件到使用64位API

要更新MEX源代码,请使用以下清单。

  1. 检查代码的用法公关PI.指针,由此返回的指针mxgetpr./mxgetpi.mxGetData/mxGetImagData职能。在交错的复杂API中,有一个指针,pa,返回值mxGetDoubles和其他类型化数据函数。在尝试读取数据之前,检查输入数组的复杂性是很重要的。调用mxgetpr.mxGetData在交错的复杂API中返回的结果与在单独的复杂API中返回的结果不同。

  2. 在编辑之前准备好代码。

    在修改代码之前,请验证MEX功能是否与之合作-R2017bAPI。至少,构建一个预期输入和输出的列表,或者创建一个完整的测试套件。使用这些测试将结果与更新后的源代码进行比较。结果应该是相同的。

    备份所有源文件、二进制文件和测试文件。

  3. 通过检查以下条件迭代地重新推荐现有代码。

  4. 每次修改后,使用交错的复杂API进行编译。构建mymexfile.c., 类型:

    mex -r2018a mymexfile.c.
    构建mymexfile.f., 类型:

    mex -r2018a mymexfile.f.
  5. 解决失败和警告。

  6. 每次重构后进行测试。

    将用交错的复杂API编译的MEX函数的运行结果与原始二进制文件的结果进行比较。如果存在任何差异或故障,请使用调试器调查原因。有关调试器功能的信息,请参阅编译器文档。

  7. 将构建信息添加到MEX帮助文件

使用方法检查数组复杂度mxiscomplex

如果您的代码调用mxgetpi.函数来确定数组是否具有复杂的元素,请使用mxiscomplex函数来代替。这个函数是用-R2017b-R2018aapi。在代码中搜索以下模式。

替换C源代码: :
mxArray * pa;...如果(mxgetpi(pa)){/ *进程复杂数组* /}
mxArray * pa;...if (mxIsComplex(pa)){/*处理复杂数组*/}
双* PTR;ptr = mxgetpi(pa);if(ptr!= null){/ *进程复杂阵列* /}

添加MX_HAS_INTERLEAVED_COMPLEX支持两万博1manbetx种复数表示

要编写用两个-R2017b-R2018aapi,添加MX_HAS_INTERLEAVED_COMPLEX宏。这个宏的回报真的如果使用-R2018a选择。

将以下代码包裹在一个#如果MX_HAS_INTERLEAVED_COMPLEX声明可确保此代码将构建使用-R2017b或者-R2018a梅克斯选择。然而,在本例中,在构建时没有要执行的代码-R2018a

替换C源代码: :
static void analyze_double(const mxArray *array_ptr) {mwSize total_num_of_elements, index;双* Pr,* pi;total_num_of_elements = mxGetNumberOfElements (array_ptr);公关= mxGetPr (array_ptr);π= mxGetPi (array_ptr);for(index = 0; index 
                 
static void analyze_double(const mxArray *array_ptr) {mwSize total_num_of_elements, index;total_num_of_elements = mxGetNumberOfElements (array_ptr);#if MX_HAS_INTERLEAVED_COMPLEX /* interleaved_api处理*/ mxComplexDouble *pc;mxDouble * p;if (mxIsComplex(array_ptr)) {pc = mxgetcomplexdouble (array_ptr);(指数= 0;指数< total_num_of_elements;指数+ +){mexPrintf(“= % g + % gi \ n ", (* pc) .real, (* pc) .imag);pc + +;}} else {p = mxgetdouble (array_ptr); for (index=0; index
                 
替换Fortran源代码: :
mwPointer prhs(*), pr pr = mxGetPr(prhs(1))
mpointer prhs(*), pr# if MX_HAS_INTERLEAVED_COMPLEX pr = mxget双打(prhs(1)) #else pr = mxGetPr(prhs(1)) #endif . php . php . php . php . php

使用类型化数据访问函数

使用mxGetDatamxGetImagData函数时,必须验证输入的类型mxarray.并手动将指针输出转换为正确的类型。类型化数据访问函数验证数组的类型并返回正确的指针类型。当你使用mxgetInt16s.mxGetComplexInt16s函数来处理INT16数组,您不需要记住相应的C类型,短整型

替换C源代码: :
static void analyze_int16(const mxArray *array_ptr) {short int *pr, *pi;pr = (short int *)mxGetData(array_ptr);pi = (short int *)mxGetImagData(array_ptr);if (mxIsComplex(array_ptr)){/*处理复杂数据*pr,*pi */} else{/*处理真实数据*pr */}}
static void analyze_int16(const mxArray *array_ptr) {mxComplexInt16 *pc;mxInt16 * p;if(mxIsComplex(array_ptr)) {pc = mxGetComplexInt16s(array_ptr);/*处理复杂数据(*pc).real,(*pc)。imag */}} else {p = mxGetInt16s(array_ptr);/*处理真实数据*p */}}

处理复杂的mxArrays

下面的例子展示了MATLAB如何®使用一个数组变量来表示一个复杂数组。

复杂的CmxArrays

假设您有以下复杂mxarray.变量并希望添加实数和虚数xy创建数组z.数组xy大小是一样的。

mxArray * x, y, z;

而不是创建两个指针xr西为数组x,创建一个指针xc类型的mxcomplexdouble..求元素的实部和虚部我(我), 用我[我].realXC [i] .imag

替换C源代码: :
双人* xr,* xi,* yr,* yi,* zr,* zi;/ *获取指向阵列的真实和虚部的阵列* / xr = mxgetpr(x);xi = mxgetpi(x);Yr = mxgetpr(y);yi = mxgetpi(y);zr = mxgetpr(z);zi = mxgetpi(z);... / *对元素I * / zr [i] = xr [i] + Yr [i];zi [i] = xi [i] + yi [i];
/ *获取到复杂数组的指针* / mxcomplexdouble * xc = mxgetcomplexdoubles(x);MXComplexDouble * YC = MXGetComplexDoubles(Y);mxcomplexdouble * zc = mxgetcomplexdoubles(z);... / *在元素I * / zc [i] .real = xc [i] .real + yc [i]。ZC [i] .imag = XC [i] .imag + YC [i] .imag;

下面的代码复制了一个mxarray.进入输出参数。代码显示如何测试和复制复杂数组。

替换C源代码: :
mxgetpr(plhs [0])[0] = mxgetpr(prhs [0])[index];if(mxiscomplex(prhs [0])){mxgetpi(plhs [0])[0] = mxgetpi(prhs [0])[index];}
if (mxIsComplex(prhs[0])) {mxgetcomplex双打(plhs[0])[0] = mxgetcomplex双打(prhs[0])[index];} else {mxget双打(plhs[0])[0] = mxget双打(prhs[0])[index];}

复杂的FortranmxArrays

假设有两个复星mxArrays并希望将它们传递给具有输入参数的Fortran函数xy定义如下。

复杂* 16 x (*), y (*)

而不是分别转换实部和虚部mxarray.,可以使用mxGetComplexDoubles函数。

替换Fortran源代码: :
mxGetPr, mxGetPi C复制数据到本地COMPLEX Fortran数组。调用mxCopyPtrToComplex16(+ mxGetPr(prhs(1)), + mxGetPi(prhs(1)),x,nx),y,ny)
mwpointer mxgetcomplexdouble整数* 4状态整数* 4 mxcopyptrocomplex16,mxcopycomplex16toptr c将数据复制到本机复杂的Fortran阵列中。status = + mxcopyptrocomplex16(mxgetcompleptouble(mxgetcomplexdouble(prhs(1)),x,nx)c测试状态出错状态= mxcopyptrocomplex16(mxgetcopptrocomplex16(mxgetcompleptrocomplex16(mxgetcomplexdouble(prhs(2)),y,ny)c测试状态用于错误情况

维护的复杂性mxarray.

这个C代码片段展示了如何转换一个实的双精度输入数组prhs [0]变成一个复杂的数组。下面的代码设置了用于用连续数字填充数组复杂部分的变量。

//检查参数数量和预期类型的代码mwSize cols = mxGetN(prhs[0]);mwSize sz = mxGetElementSize(prhs[0]);

下面的代码展示了如何使用mxMakeArrayComplex要将真实,双输入数组转换为交错复合mxarray..有关更多示例,请参见mxMakeArrayComplex (C)

替换C源代码: :
plhs [0] = mxDuplicateArray (prhs [0]);mxDouble* dc = (mxDouble*)mxMalloc(rows*cols*sz);mxSetImagData (plhs[0]特区);For (int I = 0;我< rows*cols;{dc[I] = I +1;}
plhs [0] = mxDuplicateArray (prhs [0]);if (mxMakeArrayComplex(plhs[0])) {mxComplexDouble *dt = mxgetcomplexdouble (plhs[0]);For (int I = 0;我< rows*cols;我+ +){dt[我]。图像放大= i + 1;} }

替换单独的复杂功能

以下函数不在交错复杂API中。在处理复杂数据时,必须用交错的复杂函数替换它们。

  • mxgetpi.

  • mxSetPi

  • mxGetImagData

  • mxSetImagData

你可以把电话转给mxgetpr.mxgetpi.号召mxGetComplexDoubles.这个函数验证数组是否包含类型为的元素mxcomplexdouble..同样的,mxSetComplexDoubles替换mxSetPrmxSetPi

mxGetDatamxGetImagData函数不检查数组的类型。相反,必须将返回值强制转换为与输入指定的类型匹配的指针类型。代替打电话mxGetDatamxGetImagData具有单个,适当的类型的数据访问功能,例如,mxGetComplexInt64s

替换C源代码: :
mxArray * pa;mwSize numElements;INT64_T * PR,* PI;pr =(int64_t *)mxgetdata(pa);pi =(int64_t *)mxgetimagdata(pa);numElements = mxGetNumberOfElements (pa);
mxArray * pa;mwSize numElements;mxComplexInt64 *电脑;电脑= mxGetComplexInt64s (pa);numElements = mxGetNumberOfElements (pa);

计算数组数据大小mxGetElementSize

在里面-R2018aAPI,这mxgetElementsize(c)函数返回sizeof (std::复杂< T >)对于一个复杂的mxarray.与数据类型T.的函数返回值的两倍-R2017bAPI。同样的,mxGetElementSize (Fortran)在里面-R2018a的函数返回两倍的值-R2017bAPI。

考虑替换将要逐步淘汰的功能

下面的函数在两个-R2017b-R2018aapi。虽然不需要用键入的数据访问功能替换它们,但是键入的数据功能提供类型检查。此外,如果你使用mxgetpr.,你可以选择mxgetpi.用于任何复杂的数组处理。这种代码模式在编写时导致错误-R2018a墨西哥人的功能。

你可以把电话转给mxgetpr.号召mxGetDoubles.这个函数验证数组是否包含类型为的元素mxDouble.同样的,mxsetdoubles.替换mxSetPr.取代对mxGetDatamxSetData函数,选择适当的键入数据访问功能,例如,mxgetInt64s.mxSetInt64s

替换C源代码: :
双* y;/*创建一个指针y到输入矩阵*/ y = mxGetPr(prhs[1]);
mxDouble * p;p = mxGetDoubles (prhs [1]);
替换Fortran源代码: :
创建一个指向输入矩阵的指针pr = mxGetPr(prhs(1))
mxgetdoublepr = mxgetdoublepr (prhs(1))

将构建信息添加到MEX帮助文件

考虑创建一个帮助文件,如使用带有MEX函数的帮助文件,其中包含构建信息。例如,创建一个文件displayTypesafeNumeric.m包含下列文字。

% displayTypesafeNumeric。m displayTypesafeNumeric C MEX函数的帮助文件%使用以下命令构建这个MEX文件:% mex -R2018a displayTypesafeNumeric.c

在MATLAB命令提示符处,输入:

帮助displayTypesafeNumeric
displayTypesafeNumeric.mHelp file for displayTypesafeNumeric C MEX function Use the following command to build this MEX file: mex -R2018a displayTypesafeNumeric.c

另请参阅

相关话题