Эта тема описывает, как обновить ваши файлы MEX, чтобы использовать чередованный комплексный API. Можно продолжить использовать отдельный комплексный API путем вызова mex
команда с -R2017b
опция. Однако для получения дополнительной информации об использовании этой опции, смотрите, что я должен Обновить Свои файлы MEX, чтобы Использовать Чередованный Комплексный API?
Примечание
Если вы создаете свои файлы MEX с помощью mex
команда с -compatibleArrayDims
опция, затем сначала необходимо обновить исходный код, чтобы использовать 64-битный API. Для получения информации смотрите файлы MEX Обновления, чтобы Использовать 64-битный API.
Чтобы обновить ваш исходный код MEX, используйте следующий контрольный список.
Рассмотрите свой код для использования pr
и pi
указатели, указатели, возвращенные mxGetPr
/mxGetPi
и mxGetData
/mxGetImagData
функции. В чередованном комплексном API существует один указатель, pa
, значение, возвращенное mxGetDoubles
и другие введенные функции данных. Важно проверять входной массив на сложность прежде, чем попытаться считать данные. Вызовы mxGetPr
и mxGetData
на комплексных массивах возвращают различные результаты в чередованный комплексный API, чем в отдельном комплексном API.
Подготовьте свой код перед редактированием.
Прежде, чем изменить ваш код, проверьте, что MEX-функция работает с -R2017b
API. Как минимум создайте список из ожидаемых вводов и выводов или создайте полный тестовый набор. Используйте эти тесты, чтобы сравнить результаты с обновленным исходным кодом. Результаты должны быть идентичными.
Поддержите весь источник, двоичный файл и тестовые файлы.
Итеративно осуществите рефакторинг свой существующий код путем проверки на следующие условия.
После каждого изменения, компиляция с помощью чередованного комплексного API. Создавать myMexFile.c
Ввод:
mex -R2018a myMexFile.c
myMexFile.F
Ввод:mex -R2018a myMexFile.F
Разрешите отказы и предупреждения.
Протестируйте после каждого рефакторинга.
Сравните результаты выполнения вашей MEX-функции, скомпилированной с чередованным комплексным API с результатами вашего исходного двоичного файла. Если существуют какие-либо различия или отказы, используйте отладчик, чтобы исследовать причину. Для получения информации о возможностях вашего отладчика обратитесь к своей документации компилятора.
mxIsComplex
Если ваш код вызывает mxGetPi
функция, чтобы определить, имеет ли массив комплексные элементы, используйте mxIsComplex
функцию вместо этого. Эта функция создает с обоими -R2017b
и -R2018a
API. Ищите свой код следующие шаблоны.
Замена C исходный код: | С: |
---|---|
mxArray *pa; ... if (mxGetPi(pa)) { /* process complex array */ } |
mxArray *pa; ... if (mxIsComplex(pa)) { /* process complex array */ } |
double *ptr; ptr = mxGetPi(pa); if (ptr != NULL) { /* process complex array */ } |
MX_HAS_INTERLEAVED_COMPLEX
поддерживать оба представления комплексного числаЗаписать код, который создает с обоими -R2017b
и -R2018a
API, добавляет MX_HAS_INTERLEAVED_COMPLEX
макрос. Этот макрос возвращает true
если вы создаете файл MEX с -R2018a
опция.
Перенос следующего кода в #if MX_HAS_INTERLEAVED_COMPLEX
оператор гарантирует, что этот код создаст с любым -R2017b
или -R2018a
mex
опция. Однако в этом примере, нет никакого кода, чтобы выполниться, когда создано с -R2018a
.
Замена C исходный код: | С: |
---|---|
static void analyze_double(const mxArray *array_ptr) { mwSize total_num_of_elements, index; double *pr, *pi; total_num_of_elements = mxGetNumberOfElements(array_ptr); pr = mxGetPr(array_ptr); pi = mxGetPi(array_ptr); for (index=0; index<total_num_of_elements; index++) { if (mxIsComplex(array_ptr)) { mexPrintf("%g + %gi\n", *pr++, *pi++); } else { mexPrintf("%g\n", *pr++); } } } |
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 complex API processing */ mxComplexDouble *pc; mxDouble *p; if (mxIsComplex(array_ptr)) { pc = mxGetComplexDoubles(array_ptr); for (index=0; index<total_num_of_elements; index++) { mexPrintf(" = %g + %gi\n",(*pc).real,(*pc).imag); pc++; } } else { p = mxGetDoubles(array_ptr); for (index=0; index<total_num_of_elements; index++) { mexPrintf(" = %g\n", *p++); } } #else /* separate complex API processing */ double *pr, *pi; pr = mxGetPr(array_ptr); pi = mxGetPi(array_ptr); for (index=0; index<total_num_of_elements; index++) { if (mxIsComplex(array_ptr)) { mexPrintf("%g + %gi\n", *pr++, *pi++); } else { mexPrintf("%g\n", *pr++); } } #endif } |
Замена исходный код Фортрана: | С: |
---|---|
mwPointer prhs(*), pr pr = mxGetPr(prhs(1)) |
mwPointer prhs(*), pr #if MX_HAS_INTERLEAVED_COMPLEX pr = mxGetDoubles(prhs(1)) #else pr = mxGetPr(prhs(1)) #endif |
Использовать mxGetData
и mxGetImagData
функции, необходимо проверить тип входа mxArray
и вручную бросок указатель выход к правильному типу. Введенные функции доступа к данным проверяют тип массива и возвращают правильный тип указателя. Когда вы используете mxGetInt16s
и mxGetComplexInt16s
функции в следующем коде, чтобы обработать int16
массив, вы не должны помнить соответствующий тип C, short int
.
Замена 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)) { /* process complex data *pr,*pi */ } else { /* process real data *pr */ } } |
static void analyze_int16(const mxArray *array_ptr) { mxComplexInt16 *pc; mxInt16 *p; if(mxIsComplex(array_ptr)) { pc = mxGetComplexInt16s(array_ptr); /* process complex data (*pc).real,(*pc).imag */ } } else { p = mxGetInt16s(array_ptr); /* process real data *p */ } } } |
mxArrays
Следующие примеры показывают, как MATLAB® использует одну переменную типа массив, чтобы представлять комплексный массив.
mxArrays
C
Предположим, что у вас есть следующий комплексный mxArray
переменные и хотят добавить вещественные числа и мнимые числа x
и y
создать массив z
. Массивы x
и y
одного размера.
mxArray * x, y, z;
Вместо того, чтобы создать два указателя xr
и xi
для массива x
, создайте один указатель xc
из типа mxComplexDouble
. Получить доступ к действительным и мнимым частям элемента xc[i]
, используйте xc[i].real
и xc[i].imag
.
Замена C исходный код: | С: |
---|---|
double *xr, *xi, *yr, *yi, *zr, *zi; /* get pointers to the real and imaginary parts of the arrays */ xr = mxGetPr(x); xi = mxGetPi(x); yr = mxGetPr(y); yi = mxGetPi(y); zr = mxGetPr(z); zi = mxGetPi(z); ... /* perform addition on element i */ zr[i] = xr[i] + yr[i]; zi[i] = xi[i] + yi[i]; |
/* get pointers to the complex arrays */ mxComplexDouble * xc = mxGetComplexDoubles(x); mxComplexDouble * yc = mxGetComplexDoubles(y); mxComplexDouble * zc = mxGetComplexDoubles(z); ... /* perform addition on element i */ zc[i].real = xc[i].real + yc[i].real; 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])) { mxGetComplexDoubles(plhs[0])[0] = mxGetComplexDoubles(prhs[0])[index]; } else { mxGetDoubles(plhs[0])[0] = mxGetDoubles(prhs[0])[index]; } |
mxArrays
Предположим, что у вас есть два комплекса, двойные mxArrays
и хочу передать их функции Фортрана с входными параметрами x
и y
заданный можно следующим образом.
complex*16 x(*), y(*)
Вместо того, чтобы отдельно преобразовать действительные и мнимые части каждого mxArray
, используйте mxGetComplexDoubles
функция.
Замена исходный код Фортрана: | С: |
---|---|
mwPointer mxGetPr, mxGetPi C Copy the data into native COMPLEX Fortran arrays. call mxCopyPtrToComplex16( + mxGetPr(prhs(1)), + mxGetPi(prhs(1)),x,nx) call mxCopyPtrToComplex16( + mxGetPr(prhs(2)), + mxGetPi(prhs(2)),y,ny) |
mwPointer mxGetComplexDoubles integer*4 status integer*4 mxCopyPtrToComplex16, mxCopyComplex16ToPtr C Copy the data into native COMPLEX Fortran arrays. status = + mxCopyPtrToComplex16(mxGetComplexDoubles(prhs(1)),x,nx) C Test status for error conditions status = + mxCopyPtrToComplex16(mxGetComplexDoubles(prhs(2)),y,ny) C Test status for error conditions |
mxArray
Этот отрывок кода С показывает, как преобразовать действительный, дважды, входной массив prhs[0]
в комплексный массив. Следующие кодовые наборы переменные раньше заполняли комплексную часть массива с последовательными числами.
// code to check number of arguments and expected types mwSize rows = mxGetM(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], dc); for (int i = 0 ; i < rows*cols ; i++) { dc[i] = i+1; } |
plhs[0] = mxDuplicateArray(prhs[0]); if (mxMakeArrayComplex(plhs[0])) { mxComplexDouble *dt = mxGetComplexDoubles(plhs[0]); for (int i = 0 ; i < rows*cols ; i++) { dt[i].imag = i+1; } } |
Следующие функции не находятся в чередованном комплексном API. Необходимо заменить их на чередованные комплексные функции при обработке комплексных данных.
mxGetPi
mxSetPi
mxGetImagData
mxSetImagData
Можно заменить вызовы mxGetPr
и mxGetPi
с вызовом mxGetComplexDoubles
. Эта функция проверяет, что ваш массив содержит элементы типа mxComplexDouble
. Аналогично, mxSetComplexDoubles
замены mxSetPr
и mxSetPi
.
mxGetData
и mxGetImagData
функции не проверяют тип массива. Вместо этого необходимо бросить возвращаемое значение к типу указателя, который совпадает с типом, заданным входом. Замените вызовы mxGetData
и mxGetImagData
с одной, соответствующей, введенной функцией доступа к данным, например, 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 *pc; pc = mxGetComplexInt64s(pa); numElements = mxGetNumberOfElements(pa); |
mxGetElementSize
В -R2018a
API, mxGetElementSize (C)
функция возвращает sizeof(std::complex<T>)
для комплексного mxArray
с типом данных T
. Это значение является дважды значением, возвращенным функцией в -R2017b
API. Точно так же mxGetElementSize (Fortran)
в -R2018a
API возвращает дважды значение как функцию в -R2017b
API.
Следующие функции находятся в обоих -R2017b
и -R2018a
API. В то время как вы не должны заменять их на введенные функции доступа к данным, введенные функции данных обеспечивают проверку типа. Кроме того, если вы используете mxGetPr
, вы можете выбрать mxGetPi
для любой обработки комплексного массива. Этот шаблон кода вызывает ошибки при записи -R2018a
MEX-функции.
mxGetPr
mxSetPr
mxGetData (C)
и mxGetData (Fortran)
- для числовых массивов
mxSetData (C)
и mxSetData (Fortran)
- для числовых массивов
Можно заменить вызовы mxGetPr
с вызовом mxGetDoubles
. Эта функция проверяет, что ваш массив содержит элементы типа mxDouble
. Аналогично, mxSetDoubles
замены mxSetPr
. Заменять вызовы mxGetData
и mxSetData
функции, выберите соответствующую введенную функцию доступа к данным, например, mxGetInt64s
и mxSetInt64s
.
Замена C исходный код: | С: |
---|---|
double *y; /* create a pointer y to input matrix */ y = mxGetPr(prhs[1]); |
mxDouble *p; p = mxGetDoubles(prhs[1]); |
Замена исходный код Фортрана: | С: |
---|---|
mwPointer pr mwPointer mxGetPr C Create a pointer to input matrix pr = mxGetPr(prhs(1)) |
mwPointer pr mwPointer mxGetDoubles pr = mxGetDoubles(prhs(1)) |
Рассмотрите создание справочного файла, описанного в Использовании справочных файлов с MEX-функциями, который содержит информацию о сборке. Например, создайте файл displayTypesafeNumeric.m
содержа следующий текст.
% displayTypesafeNumeric.m Help file for displayTypesafeNumeric C MEX function % % Use the following command to build this MEX file: % mex -R2018a displayTypesafeNumeric.c
В командной строке MATLAB введите:
help displayTypesafeNumeric
displayTypesafeNumeric.m Help file for displayTypesafeNumeric C MEX function Use the following command to build this MEX file: mex -R2018a displayTypesafeNumeric.c