- •Конфигурирование MATLAB Compiler
- •Простой пример сложения двух чисел
- •Создание МЕХ-файла, использующего программу на Фортране
- •Объявление функций и локальных переменных
- •Чтение входного массива
- •Выполнение вычислений
- •Копирование полученного результата в выходную величину
- •Работа с комплексными переменными
Лекция 6 Связь Matlab c программами на языке Fortran
Довольно часто встречается ситуация, когда имеются модули, написанныенаСилиFortran,итребуетсяиспользоватьихвприложенииMatlab. Пакет Matlab предоставляет возможность вызова внешних программ благо-
даря Application Program Interface (API), то есть программному интерфейсу приложения. Функции Matlab API делятся на две категории: функции, обеспечивающие создание и доступ к массивам Matlab, и функции, позволяющие оперировать в рабочей среде Matlab. Создание МЕХ-файлов из процедур Fortran заключается в написании интерфейсной процедуры с использованием функций Matlab API и последующей генерации МЕХ-файла при помощи команды mex. Генерация МЕХ-файлов из процедур Fortran требует установки одного из компиляторов Фортрана. Встроенный компилятор Fortran не входит в пакет Matlab, в отличие от компилятора Lcc для приложений на С. Производители довольно жестко увязывают тип и версию компилятора с версией самой программы Matlab. Для выполнения генерации МЕХ-файлов необходим также компоновщик (редактор связей), который в состав компилятора не входит. Вот рекомендации фирмы MathWorks по выбору компилятора и среды, в которой происходит компоновка выходного файла
Версия |
Версия компилятора |
Среда компоновки |
|
MATLAB |
Fortran |
||
|
|||
|
|
Microsoft Visual Studio 2005 |
|
R2008a |
Intel Visual Fortran 9.1 |
Professional |
|
Intel Visual Fortran 10.1 |
Microsoft Visual Studio 2008 |
||
|
|||
|
|
Professional |
|
|
|
|
|
|
|
Microsoft Visual Studio 2005 |
|
|
|
SP1 Professional |
|
R2010b |
Intel Visual Fortran 10.1 |
Microsoft Visual Studio 2008 |
|
Intel Visual Fortran 11.1 |
SP1 Professional |
||
|
|||
|
|
Microsoft Visual Studio 2010 |
|
|
|
Professional |
|
|
|
|
|
|
|
Microsoft Visual Studio 2008 |
|
R2012b |
Intel Visual Fortran |
SP1 Professional |
|
Composer XE 2011 |
Microsoft Visual Studio 2010 |
||
|
|||
|
|
Professional |
|
|
|
|
|
R2015b |
Intel Visual Fortran |
Microsoft Visual Studio 2008 |
|
Composer XE 2011 |
SP1 Professional |
||
|
|||
|
|
|
|
|
1 |
|
Версия |
Версия компилятора |
Среда компоновки |
|||
MATLAB |
Fortran |
||||
|
|
|
|||
|
Intel Visual Fortran |
Microsoft Visual Studio 2010 |
|||
|
Composer XE 2013 |
SP1 Professional |
|
|
|
|
|
Microsoft Visual Studio 2012 |
|||
|
|
Professional |
|
|
|
|
|
|
|||
|
|
Microsoft Visual C++ 2010 |
|||
|
Intel Visual Fortran |
Professional SP1 |
|
|
|
|
Composer XE 2013 |
Microsoft Visual C++ 2012 |
|||
R2016a |
Intel Parallel Studio XE |
Professional |
|
|
|
|
2015 for Fortran |
Microsoft Visual |
C++ |
2013 |
|
|
Intel Parallel Studio XE |
Professional |
|
|
|
|
2016 for Fortran |
Microsoft Visual |
C++ |
2015 |
|
|
|
Professional |
|
|
|
|
|
|
|
|
Конфигурирование MATLAB Compiler
Перед компиляцией программ необходимо произвести некоторые установки, связанные с выбором компилятора. Если компилятор не выбран, то по умолчанию используется встроенный Lcc для приложений на С. Приступим к конфигурированию MATLAB Compiler. Наберем в командной строке
Запускается программа с интерфейсом из командной строки и предлагается автоматический поиск всех компиляторов, имеющихся на компьютере.
Введите у (подтверждение) на запрос об автоматическом поиске. Появляется список доступных компиляторов С и Fortran (который может отличаться от приведенного ниже):
2
Поскольку далее мы разберем использование внешних процедур на Fortran, то следует ввести номер соответствующего компилятора (в данном случае первый) и нажать <Enter>. Далее предлагается подтвердить сделанный выбор:
Вводиму и нажимаем<Enter>.КонфигурированиеMATLABCompiler завершено.
Простой пример сложения двух чисел
Начнем изучение создания МЕХ-файлов с самого простого примера. Предположим,что изсреды Matlab требуется вызватьпроцедуру sum,написанную на Fortran. Процедура sum складывает два вещественных числа а и b и записывает результат в с (листинг 6.1). Будем считать, что процедура sum содержится в файле mysum.f.
Листинг 6.1. Исходная процедура sum на Fortran (файл mysum.f)
subroutine sum(a, b, c)
!Процедура sum складывает два вещественных числа a и b
!и возвращает результат в с
real*8 a, b, c c = a + b
end
3
Непосредственно вызвать процедуру sum из среды Matlab, разумеется,неудастся.НеобходимонаписатьинтерфейснуюпроцедурунаFortran с использованием функций Matlab API, которая будет точкой входа МЕХфайла mysum.mexw32 (если используются 64-битные версии программ, то расширение файла будет .mexw64) при вызове функции mysum из среды Matlab. Интерфейсная процедура должна называться mexFunction и иметь четыре аргумента типа integer*4:
nrhs – число входных аргументов, с которыми будет происходить обращение к МЕХ-функции mysum из среды Matlab;
prhs – массив указателей на входные аргументы mysum;
nlhs – число выходныхаргументов,с которыми будетпроисходитьобращение к МЕХ-функции mysum из среды Matlab;
plhs — массив указателей на выходные аргументы mysum.
Обмен данными между процедурой sum и средой Matlab посредством интерфейсной процедуры mexFunction осуществляется только при помощи перечисленных аргументов. Для выделения данных из prhs и занесения результата в plhs предназначены специальные функции Matlab API. Интерфейсная для sum процедура mexFunction приведена в листинге 6.2, назовем файл с ней mysumg.f. Итак, интерфейсная процедура имеет четыре параметра типа.integer*4, два массива plhs, prhs и два скаляра nlhs, nrhs.
Листинг 6.2. Интерфейсная процедура mexFunction (файл mysumg.f)
subroutine mexFunction(nlhs, plhs, nrhs, prhs) C Интерфейсная процедура для sum
C Описание типов аргументов
integer nlhs, nrhs, plhs (*), prhs (*)
C Описание типов используемых функций из Matlab API integer mxCreateFull, mxGetPr
C Описание типов, указателей на используемые переменные
integer a_pr, b_pr, с_рr
C Описание типов используемых переменных real*8 а, Ь, с
C Получение указателей на первый и второй входные C аргументы, с которыми вызывается МЕХ-функция, C указатели хранятся в массиве prhs,
C используется функция Matlab API a_pr = mxGetPr(prhs(1)) b_pr = mxGetPr(prhs(2))
C Запись значений первого и второго входных аргументов C с указателями а_рг и b_pr в переменные а и b при
4
C помощи процедуры Matlab API
call mxCopyPtrToReal8(a_pr,. a, 1) call mxCopyPtrToReal8 (b_pr, b; 1)
C Вызов процедуры sum, которая заносит в переменную с C сумму а и Ь
call sum(a, b, с)
C Создание выходного аргумента — вещественного массива
C размера один на один при помощи функции Matlab API, C выходной аргумент есть указатель на массив
plhs(l) = mxCreateFull(1, 1, 0) c_pr = mxGetPr(plhs(l))
C Копирование значения с в массив с указателем с_рr call mxCopyReal8ToPtr(с, с_рr, 1)
end
В mexFunction будут использоваться две функции Matlab API: mxCreateFull и mxGetPr, возвращающие значения типа integer*4. Функция mxCreateFull выделяет память под массив и возвращает указатель на массив. В рассматриваемом примере этот массив служит для возврата результата (суммы двух чисел) в рабочую среду Matlab и поэтому имеет размеры одиннаодин.ФункцияmxGetPr служитдляполученияуказателянапервый вещественный элемент в массиве. Целочисленные переменные а_рг, b_рг и с_рг понадобятся для хранения указателей на массивы, содержащие входные аргументы и выходной аргумент. Для записи значений аргументов определены вещественные переменные а, b и с.
Следует отметить, что при наборе процедур вне редактора среды Fortran следует учитывать, что первые шесть позиций в начале строки отводятся под метки, а операторы начинаются с седьмой позиции. Если пренебречь этим правилом, то при компиляции возникнут ошибки. Сообщения об ошибках выводятся в командное окно Matlab.
Процедура mexFunction начинается с получения указателей на первые (а данном случае и единственные) вещественные элементы массивов, на которые указывают первый и второй элементы prhs. Важно понимать, что массив prhs содержит указатели на массивы специального типа mxArray. Данный тип определен в Matlab API и является единственно возможным способом обмена данными между средой Matlab и процедурой на Fortran. Все данные Matlab передаются при помощи mxArray, в зависимости от типа передаваемых данных следует применять соответствующие функции для извлечения указателей. Для извлечения указателей на вещественные массивы содержащие значения входных аргументов МЕХ-функ- ции, например a_pr f bpr, используется функция mxGetPr Matlab API.
Следующий шаг состоит в записи значений входных аргументов в вещественные переменные а и b. Процедура Matlab API, которая называется
5
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
6