ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 03.05.2019
Просмотров: 694
Скачиваний: 5
6
mxCopyPtrToReal8
, заносит вещественные данные в массив, объявленный
в процедуре Fortran. Первым входным аргументом mxCopyPtrToReal8 яв-
ляется указатель, вторым – имя массива, а третьим – количество записывае-
мых элементов (в рассматриваемом примере требуется записать только
один элемент). Процедура вызывается два раза, для занесения значений
входных аргументов МЕХ-функции в переменные
а и b интерфейсной про-
цедуры mexFunction.
На данный момент в интерфейсной процедуре известны значения ар-
гументов, от которых была вызвана МЕХ-функция в среде Matlab. Данное
обстоятельство дозволяет обратиться к процедуре sum, ее использование и
было основной задачей. Результат, т.е. сумма
а и b (см. листинг 6.1), занесен
в переменную
с.
Осталось обеспечить возвращение МЕХ-функцией в выходном аргу-
менте значения переменной
с. Предварительно необходимо создать массив
при помощи функции mxCreateFull Matlab API. Первыми двумя входными
аргументами mxCreateFull являются число строк и столбцов создаваемого
массива, а третьим – ноль или единица. Ноль, указанный в третьем аргу-
менте, соответствует вещественному массиву, а единица – комплексному.
Функция mxCreateFull возвращает указатель на созданный массив, кото-
рый следует записать в plhs (1). Выше было сказано, что массив plns должен
содержать указатели на массивы с результатом, поскольку именно plhs ис-
пользуется для передачи значений в рабочую среду Matlab. Последним дей-
ствием является занесение в массив значения вещественной переменной
с,
для чего применяется процедура mxCopyReal8ToPtr Matlab API. Первый
входной аргумент mxCopyReal8ToPtr является переменной, второй – ука-
зателем на массив, подлежащий заполнению, а третий – количеством запи-
сываемых элементов массива.
Использование процедуры sum в Matlab станет возможным только по-
сле создания МЕХ-функции из sum, хранящейся в файле mysum.f и интер-
фейс-процедуры mexFunction, которая записана в файле mysumg.f. Для со-
здания МЕХ-функции служит команда mex. Перед применением mex сле-
дует определить, каким компилятором Fortran будет пользоваться Matlab
для генерации МЕХ-функций. Для этого в командной строке Matlab следует
ввести следующее:
>> mex -setup
В ответ на запрос о компиляторе выберите один из поддерживаемых
установленной версией Matlab: Digital Visual Fortran 5.0 или Compaq
Visual] Fortran 6.1
(только для Matlab версии 6.x). После настройки Matlab
на использование компилятора Fortran можно приступать к окончатель-
ному этапу – созданию МЕХ-функции. Файлы mysum.f и mysumg.f должны
находиться в текущем каталоге Matlab. Необходимо выполнить команду
mex,
указав в качестве ее параметров имена этих файлов:
>> mex mysum.f mysumg.f
7
В данной строке имя файла с интерфейсной процедурой является вто-
рым параметром mex. После выполнения данной команды в текущем ката-
логе появится файл mysum.dll, который и содержит требуемую МЕХ-функ-
цию. Проверим ее работу, обратившись к ней из командной строки:
>> s=mysum(l,2)
s =
3
Пример создания МЕХ-функции из простейшей процедуры Fortran,
приведенный выше, демонстрирует основные принципы использования ин-
терфейса приложений Matlab API. Пользователю Matlab, не имеющему до-
статочного опыта в области разработки интерфейса приложений, но желаю-
щему вызывать процедуры Fortran из среды Matlab, достаточно знать не-
большой набор функций Matlab API. Требуются только функции, которые
позволяют обмениваться основными типами данных. Интерфейсные проце-
дуры, как правило, принципиально не отличаются для различных процедур
на Fortran и состоят из трех частей:
•
получение значений входных аргументов;
•
вызов процедуры на Fortran;
•
возвращение значений в среду Matlab.
=========================================================
Пример из документации Matlab
Создание МЕХ-файла, использующего программу на Фортране
Напишем простую программу на Фортране timestwo, которая при-
нимает в качестве входного параметра действительное значение перемен-
ной, а возвращает это значение, умноженное на 2:
subroutine timestwo(y_output, x_input)
real*8 x_input, y_output
y_output = 2.0 * x_input
return
end
Создадим интерфейсную программу для вызова этой подпрограммы
на Фортране. Откроем MATLAB Editor и введем следующую информацию
C=======================================================
C timestwo.f
C
Функция, которая принимает скаляр, а возвращает его
C
удвоенное значение.
C
Это MEX-файл для MATLAB.
C=======================================================
8
Добавим заголовочный файл Фортрана fintrf.h, позволяющий под-
ключить API MATLAB.
#include "fintrf.h"
Сохраним файл в рабочую директорию MATLAB, например, на смен-
ный носитель f:\work, и назовем его timestwo.f.
Для доступа к подпрограмме на Фортране используется интерфейсная
процедура mexFunction, которая должна содержать следующий код
C
Интерфейсная процедура
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
C Declarations
C Statements
return
end
Для того, чтобы явным образом объявлять тип каждой переменной
включим в нашу программу оператор
implicit none
Явное объявление типа переменных необходимо для 64-битных мас-
сивов.
Интерфейсная процедура mexFunction имеет четыре аргумента.
Два типа mwPointer (указатели на массивы типа mxArray) и два типа inte-
ger:
nrhs –
число входных аргументов, с которыми будет происходить об-
ращение к МЕХ-функции timestwo из среды Matlab;
prhs –
массив указателей на входные аргументы timestwo;
nlhs –
число выходных аргументов, с которыми будет происходить об-
ращение к МЕХ-функции timestwo из среды Matlab;
plhs —
массив указателей на выходные аргументы timestwo.
Обмен данными между процедурой timestwo и средой Matlab посред-
ством интерфейсной процедуры mexFunction осуществляется только при
помощи перечисленных аргументов. Для выделения данных из prhs и зане-
сения результата в plhs предназначены специальные функции Matlab API.
Добавим следующий код после оператора Declarations.
C mexFunction arguments:
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
Объявление функций и локальных переменных
9
В mexFunction использованы функции MATLAB API:
mxGetPr,mxCreateDoubleMatrix, mxGetM, mxGetN
возвращаю-
щие значения типа integer. Функция mxCreateDoubleMatrix вы-
деляет память под массив и возвращает указатель на массив. В рассматри-
ваемом примере этот массив служит для возврата результата (удвоенного
значения входной величины) в рабочую среду Matlab и поэтому имеет раз-
меры один на один. Функция mxGetPr служит для получения указателя на
первый вещественный элемент в массиве. Функции mxGetM и mxGetN
возвращают количество строк и столбцов в массиве соответственно. Пере-
менная mxIsNumeric определяет является ли массив числовым.
C Function declarations:
mwPointer mxGetPr
mwPointer mxCreateDoubleMatrix
integer mxIsNumeric
mwPointer mxGetM, mxGetN
Локальные переменные x_ptr и y_ptr понадобятся для хранения
указателей на массивы, содержащие входной и выходной аргументы. Пере-
менные mrows, ncols определяют размерность массива для хранения дан-
ных. В нашем случае имеем массив 1х1.
Объявим локальные переменные для аргументов mexFunction
C Pointers to input/output mxArrays:
mwPointer x_ptr, y_ptr
Объявим переменные, характеризующие используемый массив
C Array information:
mwPointer mrows, ncols
mwSize size
Переменные x_input – входная величина, y_output – выходная
величина, используемые в подпрограмме, производящей вычисления. Эта
подпрограмма может быть размещена как в отдельном файле, так и одном
файле с интерфейсной программой.
C Arguments for computational routine:
real*8 x_input, y_output
Чтение входного массива
Указатель на массив, содержащий входные данные получаем с помо-
щью функции mxGetPr
x_ptr = mxGetPr(prhs(1))
Для создания массива Фортрана x_input, используем функцию
mxCopyPtrToReal8
.
10
C Get the size of the input array.
mrows = mxGetM(prhs(1))
ncols = mxGetN(prhs(1))
size = mrows*ncols
C Create Fortran array from the input argument.
call mxCopyPtrToReal8(x_ptr,x_input,size)
Для создания выходной величины используем функции mxCreateDou-
bleMatrix
и mxGetPr
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(mrows,ncols,0)
y_ptr = mxGetPr(plhs(1))
Выполнение вычислений
Передадим аргументы в подпрограмму timestwo.
C Call the computational subroutine.
call timestwo(y_output, x_input)
Копирование полученного результата в выходную величину
C Load the data into y_ptr,
C which is the output to MATLAB.
call mxCopyReal8ToPtr(y_output,y_ptr,size)
В окончательном виде файл timestwo.f будет выглядеть так
C ==================================================
C timestwo.f
C
Функция, которая принимает скаляр, а возвращает
C
его удвоенное значение.
C
Это MEX-файл для MATLAB.
C ==================================================
#include "fintrf.h"
C Gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
C mexFunction arguments:
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
C Function declarations:
mwPointer mxGetPr
mwPointer mxCreateDoubleMatrix