2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2  След.
 
 C/C++ и Matlab
Сообщение12.02.2006, 21:41 
Аватара пользователя
На днях меня в личке попросили объяснить, как из Matlab выдернуть код для матричных вычислений, дабы опосля их использовать в собственных глубоко бескорыстных целях. :) Поскольку об этом речь заходит как минимум, во второй раз, я решил, что лучше об этом поболтать публично, что бы всяк, кому надо мог ознакомится.

Итак, все сказанное будет пока относится только к MATLAB 5.2. & Watcom C/C++ v 11.0. Если мне удастся поэкспериментировать с другими комбинациями версий MATLAB и компиляторов Си, постараюсь сообщить.

Сначала я напишу окончательный рецепт, а потом объясню, как я к нему пришел. Задача у меня была следующая - лень было самому сочинять подпрограмму вычисления БПФ, поэтому решил выдернуть ее из MATLAB. Основная прога была написана на Borland C++ Builder 4.0, но этот компилятор не входил в список поддерживаемых моей версией MATLAB. Версия MATLAB 5.2 поддерживала следующие компиляторы:
1) Borland C/C++ 5.x,
2) Microsoft Visual C++ (версии 4.2 или 5.0)
3) Watcom C/C++ 10.4 или 11.0.

 
 
 
 
Сообщение12.02.2006, 21:53 
Аватара пользователя
Из всего списка компиляторов у меня был только Watcom 11.0. Поэтому я решил сварганить DLL, которую затем присобачить к основной проге (форматы объектных файлов тоже оказались несовместимыми, во всяком случае у меня слинковать выход Watcom'a с основной прогой не получилось).

Сначала код программы (это одна процедура, которая на вход получает 3 параметра: указатель на комплекное число (т.е комплексный массив) - сюда помещается результат, указатель на double - это массив входных данных и число элементов массива):
файл fourier.cpp:
Код:
#include <math.h>
#include <windows.h>
#include <complex.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

#include "matlab.h"

//void gethtl(double *ht, double *response, double *action, int len);
void fourier_transform(complex *res, double *inp, int length);

int APIENTRY LibMain( HANDLE hinstDLL, DWORD  fdwReason,
                       LPVOID lpvReserved )
{
    return 1;
}

void fourier_transform(complex *res, double *inp, int length)
{
//Create double matrix:
    mxArray *mxdata = mxCreateDoubleMatrix(length, 1, mxREAL),
            *mxres;
//Copy input data to matrix:
    memcpy(mxGetPr(mxdata), inp, length*sizeof(double));
//FFT:
    mxres = mlfFft(mxdata, 0, 0);
//Return result:
    double *re = mxGetPr(mxres),
           *im = mxGetPi(mxres);
    while(length--)
    {
       complex z(*re++,*im++);
       *res++ = z;
    }
    mxDestroyArray(mxdata);
    mxDestroyArray(mxres);
}

#ifdef __cplusplus
}
#endif

Файл fourier.h:
Код:
#ifndef _MATLAB_GETHTL_H
#define _MATLAB_GETHTL_H

extern "C" __declspec( dllexport ) void
fourier_transform(complex *res, double *inp, int length);

#endif


В файле matlab.h (он находится в директории [MATLAB5_directory]\extern\include) объявлены прототипы большинства функций, которые можно выдернуть из MATLAB. Матричных операций тут пока что нету... Как узнаю, как назыв-ся функции-эквиваленты матричных операций - напишу. Скорей всего, они должны начинаться с букв mlf.

 
 
 
 
Сообщение12.02.2006, 22:40 
Аватара пользователя
Теперь о том, как это все скомпилить и слинковать.
1) Сначала самое простое - откомпилировать файл .cpp след. командой (по-моему, почти все опции обязательны, окромя -e25):
wpp386 -e25 -fpi87 -3s -zp8 -ei -bm -zq -Ic:\matlab\extern\include -Ic:\matlab\simulink\include -DARRAY_ACCESS_INLINING -ox fourier.cpp

Понятно, что c:\matlab надо заменить на путь, каталог, куда установлен Matlab.
2) Перед связываением надо сделать lib - файлы из некоторых dll-ок следующими командами:
wlib -q -n libmfile.lib c:\matlab\bin\libmmfile.dll
wlib -q -n libmcc.lib c:\matlab\bin\libmcc.dll
wlib -q -n libmatlb.lib c:\matlab\bin\libmatlb.dll
wlib -q -n libmx.lib c:\matlab\bin\libmx.dll
wlib -q -n libmat.lib c:\matlab\bin\libmat.dll

3) Ну и собственно, связывание:
wlink name fourier system nt_dll export fourier_transform option caseexact,quiet @fourier.lk

Тут fourier.lk - файл, находящийся в текущем каталоге, содержащий путь к файлам .lib и список файлов .lib, что мы сделали раньше и файлов .obj. Содержимое файла fourier.lk:

LIBPATH c:\matlab\extern\lib\stdalone
library LIBMAT.LIB
library LIBMATLB.LIB
library LIBMCC.LIB
library LIBMFILE.LIB
library LIBMX.LIB
file fourier.obj

Тут тоже надо поменять c:\matlab на тот каталог, куда фактически установлен Matlab.

 
 
 
 
Сообщение12.02.2006, 23:27 
Аватара пользователя
Теперь о том, как я узнавал, какая функция чего делает.
В MATLAB встроен транслятор mcc, переводящий скрипты MATLAB в текст программы на языке Си. Набиваем help mcc, среди кучи опций будет такая (вторая по счету):
Цитата:
e External. Translate M-file to a C-file that may be linked
with the MATLAB C Math Library and executed outside of the
MATLAB environment. Compile into stand-alone application
when file name is "main.m" or a C-file is specified.
See the m option.

Похоже, это то что надо, если хочешь использовать MATLAB C Math Library в своей проге, и что бы после сборки она работала без установленного MATLAB'а.
Мне захотелось узнать, что за функции выполняют матричное деление, умножение и сложение. Я написал следующий файл(division.m):
Код:
function y = division(a, b)
x = a/b;

c = a*b;

y = c+x;


и в окне команд набрал:

mcc -e division.m

после чего у меня образовался файл division.с длиной примерно в 220 строк (я уж не буду его тут приводить). 99% этого текста - ненужная лирика, но из него удалось понять, что деление выполняет процедура mccRightDivide(x, a, b) для комплексных чисел и mccRealRightDivide(x, a, b) для вещественных, первый операнд - результат, второй - делимое, третий - делитель. Аналогично, умножение для комплексных и вещественных матриц выполняют процедуры mccMultiply(y, a, b) и mccRealMatrixMultiply(y, a, b) соответственно. Процедуры сложения, увы, нет - сложение делается "ручками", в цикле.

 
 
 
 
Сообщение13.02.2006, 10:52 
Аватара пользователя
У меня вот еще вопрос, связанный с MatLAB. Я не ах какой программист - немножко сталкивался с Паскалем, Java, FoxPro ну и в основном работаю с MatLAB. Одна из, на мой взгляд, интересных особенностей MatLAB в том, что одна и та же функция (без перегрузки функций) может принимать один, два, ... -дцать аргументов. Отсюда два вопроса:
1) Могут ли эти особенности быть перенесены из MatLAB в тот же C, если да, то как это реализуется?
2) Является ли этот случай уникальным или какие-то другие языки тоже используют такие подходы?

 
 
 
 
Сообщение13.02.2006, 13:36 
Аватара пользователя
Да, такая штука точно есть в Си и Паскале. В Си это самая что ни на есть известная функция printf, она принимает переменное число аргументов. Но я сам этой особенностью ни разу не пользовался (в смысле - не писал таких функций). :(

 
 
 
 
Сообщение13.02.2006, 15:10 
Аватара пользователя
Да, и есче - плохие новости. В MATLAB начиная с версии 5.3 похоже нельзя создать совершенно автономное приложение - все равно будут использоватся dll, входящие в состав MATLAB. :(

 
 
 
 
Сообщение13.02.2006, 16:03 
Аватара пользователя
Sanyok писал(а):
В MATLAB начиная с версии 5.3 похоже нельзя создать совершенно автономное приложение - все равно будут использоватся dll, входящие в состав MATLAB. :(
:cry: А у меня 6.5. Ну dll - еще пол беды, вот FEMLab-программы вообще не знаю можно ли хоть как-то перенести...

 
 
 
 
Сообщение14.02.2006, 10:13 
Аватара пользователя
Ну, 6.5 у меня нету... Кстати, интересно поэкспериментировать... Мож, политика опять изменилась, и снова можно stand-alone application клепать... :)

 
 
 
 
Сообщение15.02.2006, 14:19 
Аватара пользователя
Sanyok писал(а):
Ну, 6.5 у меня нету... Кстати, интересно поэкспериментировать...

Кстати, есть уже и версия 7, но настоятельно НЕ рекомендую ставить ее - она какая-то глючная: проблемы с графикой возникают и с некоторыми toolbox-ами, а если надумаете ставить свежее - рекомендую пока остановиться на 6.5 - вроде устойчиво работает.

Еще интересный вопрос. Представим, что у нас много переменных с похожими именами и надо делать что-то с ними общее. Например, у меня была задача: много полей ввода и по нажатию кнопки надо проверять на корректность ввод во все поля: это должны быть числа, в заданном диапазоне, возможно, в экспоненциальном формате - если так, то преобразовать их в double. Я свои поля реализовал как массив полей, но не всегда удобно из того, что создается по умолчанию, переходить к массиву. Тут либо для каждой переменной (в моем случае поле ввода) вызывай функцию обработки, либо, если язык позволяет такую возможность, создать массив указателей на эти переменные, тогда можно крутить в цикле - во всяком случае программа будет иметь меньше строк. В MatLAB я знаю удобный инструмент - функции eval и feval. Есть ли в других языках аналоги? Чтобы понять, о чем я спрашиваю, вот пример кода MatLAB:

Код:
a1=1;
a2=2;
a3=3;
for i=1:3
    eval(sprintf('a%s=a%s+1',int2str(i),int2str(i)));
end


В результате этого a1, a2 и a3 увеличены на единицу.

 
 
 
 Cи & Matlab
Сообщение20.09.2006, 21:10 
Аватара пользователя
Скажите какими способами можно интегрировать с/с++ и Matlab?

 
 
 
 
Сообщение21.09.2006, 00:15 
Для МATLAB 6.5 R12 та VC++6:

Это совет Matlab: If you want to use the MATLAB Visual Studio add-in with the MATLAB C/C++
Compiler, you must start MATLAB and run the following commands:
Обратите внимание: Если Вы хотите использовать MATLAB Visual Studio с
MATLAB C/C ++ компилятором, Вы должны запустить MATLAB и выполнить
следующие команды:

cd(prefdir);
mccsavepath;


По непонятной причине вышеприведенное у меня не сработало. Зато сработало другое, а именно:
1 Запустить Matlab.
2 Путь к папке с простым м-файлом, например, exercise.m.
3 Команда: mcc -B sglcpp exercise
Реакция:
Select a compiler:
[1] Microsoft Visual C/C++ version 6.0 in D:\Program Files\Microsoft Visual Studio

[0] None
Compiler: 1

Подробности потом, если это интересно.

 
 
 
 Re: Cи & Matlab
Сообщение21.09.2006, 02:31 
antoshka1303 писал(а):
Скажите какими способами можно интегрировать с/с++ и Matlab?

Вы можете:
- писать функции на С и вызывать их из Matlab;
- Вызывать Matlab Engine из программы на С.
Об этом можно прочитать, например, в книге: Н.Н.Мартынов, А.П.Иванов. MATLAB 5.X: вычисления, визуализация, программирование - М. 2000.

 
 
 
 
Сообщение21.09.2006, 13:28 
Аватара пользователя
Продолжу тему связи СКМ с языками программирования.

Пробовал ли кто-нибудь связать Maple с Си? Я нашел пример, в книге Матросова Maple 6. Там господин Матросов пишет, точно не помню, что мол вот пример связи из help'а, но он что-то не работает. Так вот --- может кто реализовал? Я не упонимаю конвертацию кода в Си.

 
 
 
 
Сообщение22.09.2006, 13:24 
Также можно использовать библиотеки MATLAB в своих проектах и многое другое...
Но только зачем это нужно?

Нужно расширить MATLAB или взять из него что-то в свой проект, типа решателя или хитрых функций?

 
 
 [ Сообщений: 20 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group