I am trying to set up a connection between Visual Studio 10 and Mathematica 8.0 on a Windows system. I found several sources of information on the Wolfram website, but I get entirely lost. Most of the info deals with calling C++ functions from within Mathematica, but I would like it the other way round. I have quite a lot of functionality in my C++ code and I just call Mathematica to make some integral calculations.
Is there a good step-by-step approach to set up this connection? What files should I include in my project? What settings need to be changed? Does anyone have a complete example of pieces of code that gives insights in the general approach? That would be a great help.
I followed the standard instructions to add the lib
, bin
and include
to the Visual Studio directories.
More specifically, I was also wondering whether in this case I also need to make a .tm
file? Should it be empty then?
The example
here looks very clear, but this is approached from a Linux/Mac perspective.
I hope someone could bring me some guidance.
Taking into account your suggestions, I have developed the following program, but there seems to be a problem with retrieving the packages. I have put the entire code here.
The program first sends some variables to Mathematica kernel and then it should perform the integral calculation. I am only interested in the final payoff that is calculated by Mathematica. While debugging, it seems to be that the program gets stuck in the removal of all the packages (in the loop just after sending the integral function). There is no problem with the function, I guess, because it performs the calculation perfectly when I just use Mathematica.
#include <stdio.h>
#include <stdlib.h>
#include "mathlink.h"
static void init_and_openlink( int argc, char* argv[]);
static void error( MLINK lp);
MLENV ep = (MLENV)0;
MLINK lp = (MLINK)0;
int main(int argc, char* argv[]){
int pkt;
float payoff;
init_and_openlink( argc, argv);
Now, I send the different parameters and the final function of interest:
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "mue");
MLPutReal(lp,0.25);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "mui");
MLPutReal(lp,0.25);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "lambdae");
MLPutReal(lp,0.25);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "lambdai");
MLPutReal(lp,0.25);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "sigmap");
MLPutReal(lp,0.05);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "betae");
MLPutReal(lp,0.05);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "betai");
MLPutReal(lp,0.05);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "gammae");
MLPutReal(lp,0.05);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "gammai");
MLPutReal(lp,0.10);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "d");
MLPutReal(lp,0.2);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "experience1");
MLPutInteger(lp,2);
MLEndPacket(lp);
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"SetDelayed",2);
MLPutString(lp, "experience2");
MLPutInteger(lp,3);
MLEndPacket(lp);
MLPutFunction( lp,"EnterTextPacket",1);
MLPutString(lp,"expectedpayoff1bis[i1_, b1_,i2_,b2_] := NIntegrate[PDF[NormalDistribution[(1 + (betae*Exp[-mue*experience1] + betai*Exp[-mui*i1]))*(1 + b1/100), (1 + (betae*Exp[-mue*experience1] + betai*Exp[-mui*i1]))*(1 + b1/100)* Sqrt[sigmap^2 + (gammae*Exp[-lambdae*experience1])^2 + (gammai*Exp[-lambdai*i1])^2]], x]*(1 - CDF[NormalDistribution[(1 + betae*Exp[-mue*experience2] + betai*Exp[-mui*i2])*(1 + b2/100), (1 + betae*Exp[-mue*experience2] + betai*Exp[-mui*i2])*(1 + b2/100)*Sqrt[sigmap^2 + (gammae*Exp[-lambdae*experience2])^2 + (gammai*Exp[-lambdai*i2])^2]], x]), {x, 0, 2}]*(NIntegrate[(x*PDF[NormalDistribution[(1 + (betae*Exp[-mue*experience1] + betai*Exp[-mui*i1]))*(1 + b1/100), (1 + (betae*Exp[-mue*experience1] + betai*Exp[-mui*i1]))*(1 + b1/100)* Sqrt[sigmap^2 + (gammae*Exp[-lambdae*experience1])^2 + (gammai*Exp[-lambdai*i1])^2]], x]*(1 - CDF[NormalDistribution[(1 + betae*Exp[-mue*experience2] + betai*Exp[-mui*i2])*(1 + b2/100), (1 + betae*Exp[-mue*experience2] + betai*Exp[-mui*i2])*(1 + b2/100)*Sqrt[sigmap^2 + (gammae*Exp[-lambdae*experience2])^2 + (gammai*Exp[-lambdai*i2])^2]], x])/NIntegrate[PDF[NormalDistribution[(1 + (betae*Exp[-mue*experience1] + betai*Exp[-mui*i1]))*(1 + b1/100), (1 + (betae*Exp[-mue*experience1] + betai*Exp[-mui*i1]))*(1 + b1/100)*Sqrt[sigmap^2 + (gammae*Exp[-lambdae*experience1])^2 + (gammai*Exp[-lambdai*i1])^2]], x]*(1 - CDF[NormalDistribution[(1 + betae*Exp[-mue*experience2] +betai*Exp[-mui*i2])*(1 + b2/100), (1 + betae*Exp[-mue*experience2] + betai*Exp[-mui*i2])*(1 + b2/100)*Sqrt[sigmap^2 + (gammae*Exp[-lambdae*experience2])^2 + (gammai*Exp[-lambdai*i2])^2]], x]), {x, 0, 2}]), {x, 0, 2}] - (1 + (betae*Exp[-mue*experience1] + betai*Exp[-mui*i1])) - d*i1/100) - (1 - d)*i1/100");
MLEndPacket(lp);
I don't need any of the information retrieved from the above packages, so I try to get rid of everything. This is were the debugging is in a loop (When I pause the debugging, I get the screen with "no source available".
while ((pkt=MLNextPacket(lp),pkt)&&pkt!=RETURNPKT) {
MLNewPacket(lp);
if (MLError(lp)) error(lp);
}
MLNewPacket(lp);
Afterwards I want to evaluate the function and the result needs to be printed on the screen. This is the only output I am interested in:
MLPutFunction( lp,"EnterExpressionPacket",1);
MLPutFunction(lp,"expectedpayoff1bis",4);
MLPutInteger(lp,2);
MLPutInteger(lp,10);
MLPutInteger(lp,4);
MLPutInteger(lp,12);
MLEndPacket(lp);
while( (pkt = MLNextPacket( lp), pkt) && pkt != RETURNPKT) {
MLNewPacket( lp);
if (MLError( lp)) error( lp);
}
MLGetReal( lp,&payoff);
printf( "payoff: %f", payoff);
MLPutFunction( lp, "Exit", 0);
return 0;
}
The rest of the code is retrieved from the examples
static void error( MLINK lp){
if( MLError( lp)){
fprintf( stderr, "Error detected by MathLink: %s.\n",MLErrorMessage(lp));
}
else{
fprintf( stderr, "Error detected by this program.\n");
}
exit(3);
}
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[]){
#if MLINTERFACE >= 3
int err;
#else
long err;
#endif /* MLINTERFACE >= 3 */
ep = MLInitialize( (MLParametersPointer)0);
if( ep == (MLENV)0) exit(1);
atexit( deinit);
#if MLINTERFACE < 3
lp = MLOpenArgv( ep, argv, argv + argc, &err);
#else
lp = MLOpenArgcArgv( ep, argc, argv, &err);
#endif
if(lp == (MLINK)0) exit(2);
atexit( closelink);
}
addtwo
, the instructions say that you should use it with theInstall
function. If you compiled my example for calling Mma from C, run it from the command line using the command line options from my answer, substituting the correct absolute path to the Mma kernel for the-linkname
option. $\endgroup$