|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
发信人: observer (笑看人生), 信区: Science
标 题: mathematica 和 C/C++的混合编程 -observer
发信站: Unknown Space - 未名空间 (Thu May 27 14:49:38 2004), 转信
网上已经有matlab 和 c的混合编程,
我就来写个mathematica 和 C/C++的混合编程吧,只图方便
- observer
mathematica的数学运算在有些方面比 matlab 要全一些,symbolic computing就不
用说了,
比如我感兴趣的 non-square的矩阵求逆, mathematica可以直接做,
matlab还要自己调svd,剔除无效singular value,再算逆矩阵,
还有spherical harmonics,mathematica 可以直接求
当然matlab和mathematica 我两个都用,
我比较喜欢的是用mathematica和matlab完成那些公式函数太多的运算,
调函数的方式在matlab和mathematica下效率是优化过的,所以不慢
而剩下的“苦”活就由我用c/c++来写好了
以下基于mathematica 5.0 的 mathlink 和 VC6,
mathlink支持很多接口,包括tcp/ip, 也就是装mathematica的机器可以不在本地
mathematica 好象没有做成 matlab那样,可以直接调用dll
而是用一个 mathlink的c/c++ 接口,即你的程序只和mathlink建立连接,
由mathlink启动mathematica kernal并将结果返回给你。
也就是说当你调用mathmatic函数时,mathematica主程序是单独运行的
(1) 先配置vc 的ide
把mathematica 为 vc写的include, lib, bin 目录加到 vc->tools->directories
, 怎么加不用说了吧
mathematica 的这些目录缺省在
C:Program FilesWolfram ResearchMathematica.0AddOnsMathLinkDevelo
perKitWindowsCompilerAdditionsMLDev32
(2) 在你的vc project->settings->link->library modules下加入mathematica 的
lib文件"ML32I2M.LIB"
否则link你的程序时那些接口函数会找不到地
别的编译器也有mathematica提供的类似的lib文件,就不多说了
至于dll文件在你装mathematica时就设置好了,不用操心
(3) 在你的接口程序中 include mathlink的头文件"mathlink.h"
下面来分两种情况说混合编程
1. C/C++ 中调用mathematica
例子是从 help doc里面改出来的,运行通过
唯一要说明的是当建立mathlink时提示要找的exe是mathematica的keneral
而不是你自己程序编译出来的exe
如果参数用
-linkname "mathematica 的 kernal程序的完整路径"
可以省却每次都去找路径的麻烦
[php]
/* To run this program use the command-line below:
* Unix: quotient -linkname "math -mathlink"
* Mac or Windows: quotient -linkmode launch
*/
#include <stdio.h>
#include <stdlib.h>
#include "mathlink.h"
extern int mlmactty_init( char*** argvp);
static void init_and_openlink( int argc, char* argv[]);
MLENV ep = (MLENV)0;
MLINK lp = (MLINK)0;
int main( int argc, char* argv[])
{
int pkt, m, n, q;
init_and_openlink( argc, argv);
MLActivate(lp);
// printf( "Two integers m/n: ");
// if( scanf( "%d/%d", &m, &n) != 2 && scanf( "%d %d", &m, &n) != 2)
// exit(-1);
m = 4;
n = 2;
/* Send EvaluatePacket[ Quotient[ m, n]] */
MLPutFunction( lp, "EvaluatePacket", 1L);
MLPutFunction( lp, "Quotient", 2L);
MLPutInteger( lp, m);
MLPutInteger( lp, n);
MLEndPacket( lp);
/* skip any packets before the first ReturnPacket */
while( (pkt = MLNextPacket( lp), pkt) && pkt != RETURNPKT)
MLNewPacket( lp);
/* inside the ReturnPacket we expect an integer */
MLGetInteger( lp, &q);
printf( "quotient = %d ", q);
/* quit Mathematica */
MLPutFunction( lp, "Exit", 0);
return 0;
}
static void deinit( void)
{
if( ep) MLDeinitialize( ep);
}
static void closelink( void)
{
if( lp) MLClose( lp);
}
static void init_and_openlink( int argc, char* argv[])
{
long err;
#if MACINTOSH_MATHLINK
MLYieldFunctionObject yielder;
argc = mlmactty_init( &argv);
#endif
ep = MLInitialize( (MLParametersPointer)0);
if( ep == (MLENV)0) exit(1);
atexit( deinit);
#if MACINTOSH_MATHLINK
yielder = MLCreateYieldFunction( ep, NewMLYielderProc( MLDefaultYielder
, 0);
#endif
lp = MLOpenArgv( ep, argv, argv + argc, &err);
if(lp == (MLINK)0) exit(2);
atexit( closelink);
#if MACINTOSH_MATHLINK
MLSetYieldFunction( lp, yielder);
#endif
}
[/php]
上面程序用几个接口函数将命令传给mathlink, 再从mathlink得到结果
命令具体格式和含义就看help 吧
(2) mathematica 调 c/c++
这个呢就比上面稍微麻烦一点
以mathematica 提供的例子 addtwo 为例
(缺省在C:Program FilesWolfram ResearchMathematica.0AddOnsMathLin
kDeveloperKitWindowsMathLinkExamples"下可以找到)
值得注意的是为了调用c/c++写的函数,需要声明该函数在mathematica里面的接口
,
就是如文件addtwo.tm所示的东西
[php]
int addtwo P(( int, int));
: Begin:
: Function: addtwo
: Pattern: AddTwo[i_Integer, j_Integer]
: Arguments: { i, j }
: ArgumentTypes: { Integer, Integer }
: ReturnType: Integer
: End:
: Evaluate: AddTwo::usage = "AddTwo[x, y] gives the sum of two machine in
tegers x and y."
[/php]
然后用 前面提到的 bin 目录下的MPREP.EXE生成接口申明的addtwotm.c文件,
和addtwo.c的源c文件一块编译
注意,生成addtwotm.c这一步可以用vc ide 的custom build 完成即
include addtwo.tm 到你的project中去
project->setting->custom build->
在左边文件列表中选addtwo.tm, 在右边的commands中填入
mprep addtwo.tm -o addtwotm.c
在右边的ouput中填入
$(OutDir)addtwotm.c
第一次编译时就会在debug目录下输出addtwotm.c文件
include it 到你的project中,就可以编译通过了
运行时到mathematica中,
link = Install[LinkLaunch["AddTwo"]];
就会要你找到该外部命令的exe,也就是刚刚编译出来的exe
剩下的就是在mathematica中敲
AddTwo[2, 3]之类的运行该命令了
网上URL:
www.mathematica.com
http://documents.wolfram.com/v5/ ... /Windows/index.html
上面的例子我都运行通过了,如果我有什么遗漏,欢迎指正
嗯,版权归observer所有
--
※ 来源:.Unknown Space - 未名空间 mitbbs.com.[FROM: 141.210.]
(按:呵呵,Mathematica Dos版是我上大学用的第一个数学计算软件,不过后来基本使用Matlab啦。存个目,以防万一吧) |
|