Существует
несколько способов взаимодействия
системы MATLAB с внешними программами:
- Во-первых, можно написать расширение MATLAB на обычных языках программирования, таких как С/С++, Fortran и т.п.
- Наоборот, можно вызвать вычислительное ядро MATLAB из своей программы и получить результат вычислений среды MATLAB в свою программу. В этом случае MATLAB выступает как своего рода вычислительный сервер для внешней программы.
- Средой MATLAB можно управлять при помощи команд DDE (Dynamic Data Exchange) или ActiveX (OLE) Automation.
- Наконец, можно просто обмениваться данными со средой MATLAB через MAT-файлы, структура которых описана в документации к системе.
Далее
будет разобран первый способ.
Обычно
пользователь-программист работает с
системой MATLAB непосредственно, кодируя
необходимые алгоритмы на встроенном
языке MATLAB. Встроенный язык весьма удобен
для написания математических алгоритмов
- писать и отлаживать на нем программу
обычно занимает значительно меньше
времени, чем на обычных языках
программирования.
Однако,
довольно часто эффективность подобных
программ оставляет желать лучшего. Как
правило, подобная ситуация возникает,
когда алгоритм плохо векторизуется,
например, при обработке матриц нельзя
выразить этот алгоритм, пользуясь
векторными операторами языка MATLAB, и
приходится писать вложенные циклы,
перераспределять память и т.п. В этом
случае программа на языке С будет
исполняться во много раз быстрее
аналогичной программы на языке MATLAB. А
ведь довольно часто время счета
математической задачи может исчисляться
сутками.
Кроме
того, иногда возникают ситуации, когда
те или иные сложные алгоритмы уже были
реализованы на других языках
программирования. В этом случае также
будет быстрее не переписывать весь
алгоритм на языке MATLAB, а написать
относительно небольшой "переходник"
от MATLAB к уже существующему на языке С
модулю и вызвать его из среды MATLAB
напрямую.
Для
того, чтобы написать модуль, расширяющий
набор функций MATLAB, нужно создать обычную
динамическую библиотеку (DLL) для Microsoft
Windows со специальным набором функций
(интерфейсом). Данная библиотека может
быть создана при помощи многих компиляторов
языка С/С++, однако, наиболее часто
используется компилятор разработки
компании Microsoft - Visual C++.
В
документации по системе MATLAB для подобных
расширений употребляется термин MEX-файл
(Matlab EXtension), и сама MATLAB по этому расширению
имени файла может определить, что данный
модуль является ее расширением. Хотя,
специально назначать MEX в качестве
расширения имени файла необязательно,
MATLAB может прекрасно работать и со
стандартным расширением подобных
динамических библиотек — DLL.
Создание
MEX–файлов на входном языке компилятора
позволяет максимально использовать
производительность компьютера, так как
есть возможность написать наиболее
оптимальный код. Перед пользователем
открываются все возможности языка C++
(например, создание классов), можно
делать вставки на Ассемблере,
при этом сохраняются возможности
графического интерфейса MATLAB. Написание
MEX–файлов “руками” оправдано для
критичных по времени вычислений,
например, статистические испытания
объекта.
Для создания MEX–файлов на входном языке компилятора необходим непосредственно ANSI C/C++ компилятор, Visual Studio 2008 или компилятор, встроенный в среду MATLAB. Для возможности компиляции в среде MATLAB при его установке выбирать дополнительные компоненты MATLAB Compiler, C Math Library или C++ Math Library необязательно. Но для уверенности лучше сделать это, т. к. после установки одного из компиляторов, с помощью которого далее планировалось компилировать программу в среде MATLAB, могут возникнуть проблемы совместимости версий компилятора и MATLAB. А после установки вышеописанных пакетов, можно использовать собственный компилятор MATLAB.
Каждый MEX–файл включает следующие фрагменты кода:
Точка входа;
Анализ корректности входных/выходных аргументов;
Связывание с локальными переменными входных и выходных аргументов;
Тело программы;
Выход из программы.
Для
примера рассмотрим простейшую программу,
написанную на языке С (исходный код
программы взят из примеров MATLAB
и
затем усовершенствован с целью упрощения
восприятия и изменения функционала).
На вход этой программы необходимо подать
строку из любых символов, например
'123'.
На
выходе получится строка '234',
т. е.
к каждому символу будет прибавлена
единица. Если же подать строку 'abcdef',
то
на выход программа выдаст строку
'bcdefg'.
Далее
приведен и разобран текст программы.
#include "mex.h"void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ int i; char *str; int j; mwSize nelem; mxChar *x, *y; if (nrhs > 1) mexErrMsgTxt("Не надо так много параметров!"); if (nlhs > 1) mexErrMsgTxt("Слева должно быть имя одной переменной, в которую запишется результат работы программы!");
if(!mxIsChar(prhs[0])) mexErrMsgTxt("На входе должен быть текст!"); str = mxArrayToString(prhs[0]);
plhs[0] = mxCreateCharMatrixFromStrings((mwSize)nrhs, &str);
nelem = mxGetNumberOfElements(plhs[0]); x = (mxChar *)mxGetData(prhs[0]); y = (mxChar *)mxGetData(plhs[0]);
for(j=0; j < nelem; j++) { y[j] = x[j] + 1; } mxFree(str);
}
Строка
#include
“mex.h” нужна
для работы программы с функциями,
необходимыми для создания mex-файла
из исходной программы, написанной на
языке программирования С.Разберем
текст программы по фрагментам.
Точка входа.
Каждый
MEX–файл имеет точку входа — часть кода,
с которой начинается выполнение
программы. Такой точкой является функция
mexFunction:
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { // дальнейший код на C/C++ }
Переменные
nlhs и nrhs содержат соответственно число
выходных и входных переменных (аргументов).
Элементами массивов plhs и prhs являются
указатели на значения аргументов.
Анализ
аргументов.
Если
есть вероятность некорректного ввода
входных аргументов, то имеет смысл
осуществить проверку на количество,
размерность и тип входных аргументов,
а также на количество выходных аргументов.
В данной программе для этого предназначены
следующие строки:
if (nrhs > 1) mexErrMsgTxt("Не надо так много параметров!"); if (nlhs > 1) mexErrMsgTxt("Слева должно быть имя одной переменной, в которую запишется результат работы программы!");
if(!mxIsChar(prhs[0])) mexErrMsgTxt("На входе должен быть текст!");
Например,
если попробовать вызвать эту программу
и передать ей в качестве входных
аргументов, допустим, две строки, то
получите соответствующее сообщение.Связывание с локальными переменными входных и выходных аргументов.
Что
бы работать со значениями аргументов
входа и выхода, их необходимо связать
с локальными переменными,
для чего в данной программе используются
следующие строки:
str = mxArrayToString(prhs[0]);plhs[0] = mxCreateCharMatrixFromStrings((mwSize)nrhs, &str);nelem = mxGetNumberOfElements(plhs[0]);x = (mxChar *)mxGetData(prhs[0]);y = (mxChar *)mxGetData(plhs[0]);
Теперь
можно работать с локальными переменными
в, собственно, теле программы.
Тело
программы.
Тело
программы заключено в следующих пяти
строках:
for(j=0; j < nelem; j++) { y[j] = x[j] + 1; } mxFree(str);
Работа
тела программы в комментариях не
нуждается.Выход.
При
завершении подпрограммы (окончание
блока mexFunction(...)
{…}) в
среду MATLAB
возвращаются
связанные с массивом plhs
значения.
Как
начать.
Для
того чтобы испробовать работу этой
небольшой программы, необходимо сделать
следующие шаги (при уже установленной
среде MATLAB
со
всеми дополнительными пакетами)
:
1. Создать текстовый файл с расширением .c (название любое) и скопировать в него код программы, предложенный выше.
2. В главном окне MATLAB установить рабочую директорию, т.е. ту, в которой содержится текстовый файл с кодом программы.
3. В окне управления MATLAB необходимо ввести команду mex -setup для конфигурирования системы. Далее в предложенных вариантах надо выбрать подходящий компилятор для написанной программы. В данном случае можно остановиться на стандартном компиляторе под названием "Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010a\sys\lcc". Затем утвердить свой выбор. Конфигурирование закончено (Рис.1).
4. В то же окно управления ввести команду mex program.c. Если через несколько секунд в этом окне появилось приглашение на ввод следующей команды(>>), то компиляция прошла успешно, и в рабочей директории можно увидеть появившийся файл с тем же названием, но с новым расширением - mexw32.
5. Данный файл уже можно смело запускать прямо из окна управления MATLAB. Для этого необходимо ввести там следующую строку :
rez=program('12345') и нажать Ввод (Рис.2).

Рис.1. Конфигурирование системы.

Рис.2. Исполнение программы.
Аргумент
rez
в
данном случае является выходным, а
'12345'
—
входным.
Примечание:
одинарные кавычки для входного аргумента
используются, т. к. на вход программы
требуется подать текст, а эти кавычки
обозначают, что между ними находится
именно текст, даже если там введены
цифры.
Заключение:
в данном сообщении был подробно рассмотрен
пример создания mexw32
файла
из исходного кода, написанного на языке
C.
Список литературы: