14

I'm interested in calling fortran codes in a Mathematica session. I learn that Mathlink offers a way to do that. But I have little knowledge on C and nothing on C++. Is anybody willing to give me a detailed example?

I'm using with Mathematica 8, MS Visual Studio 2008 and Intel Fortran 11. The system is Windows 7 Home Premium.

Many thanks!

unstable
  • 441
  • 4
  • 10
  • 4
    http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/cb14bb903e829912 might be interesting for you. – celtschk Nov 18 '11 at 17:11
  • @celtschk, that's a very interesting link. Thanks. – rcollyer Nov 18 '11 at 17:22
  • Ha! I'm tempted to post a similar question for COBOL :D – Dr. belisarius Nov 18 '11 at 17:36
  • Do you have a very small but complete FORTRAN code sample for testing out possible solutions? I am thinking this is possible by converting FORTRAN to C with f2c and then using LibraryLink to create a dynamic library that Mathematica can load. – Arnoud Buzing Nov 18 '11 at 17:49
  • 4
    [This can also be useful.](http://stackoverflow.com/questions/8140869/minimal-effort-method-for-integrating-c-functions-into-mathematica/8152557#8152557) For MathLink you only need C, no C++ at all, and C is quite easy to learn. But for integrating it with Fortran, you may need to learn a bit about calling conventions, which is a little more advanced (unless you have some familiarity with machine internals) – Szabolcs Nov 18 '11 at 18:04
  • 3
    Searching for [c and fortran](http://stackoverflow.com/questions/tagged/c+fortran) questions reveals this [interesting answer](http://stackoverflow.com/q/7743801/7744531#7744531) regarding calling conventions for using fortran with c under gcc. – rcollyer Nov 18 '11 at 19:21
  • This costs money but might be helpful, even though it is a different Fortran: http://www.wolfram.com/products/applications/mathcodef90/ – Verbeia Nov 18 '11 at 21:47
  • 3
    The answer linked to by @rcollyer is actually more general. The Fortran ISO C Binding provides a way of calling Fortran from C, or vice-a-versa, that is part of the Fortran 2003 language standard and is therefore compiler and platform dependent. It is supported by numerous compilers in addition to gfortran & gcc. It bypasses the old issues of having to know internal calling conventions and name mangling. So if there is way to call C from Mathematica, you can call Fortran by using the ISO C Binding to cause the Fortran compiler to have your Fortran procedures use the C calling conventions. – M. S. B. Nov 18 '11 at 22:28
  • [InterCall](http://library.wolfram.com/infocenter/BySubject/Mathematica/ApplicationPackages/Independent/InterCall/) (also [here](http://www.nag.co.uk/numeric/intercall.html)) is an old program that allowed access to fortran routines via MathLink. [Apparently some compatibly was broken in Mma V3](http://forums.wolfram.com/mathgroup/archive/1999/Jan/msg00104.html) and I'm not sure what has happened since... – Simon Nov 18 '11 at 22:32
  • What about using NetLink as demonstrated here: http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/cb14bb903e829912?pli=1 – Rolf Mertig Nov 20 '11 at 17:26
  • @Mertig, this is the same link as the one posted by celtschk. Thank you both. I haven't make it work in this way so far, but I guess I need to look into the user guide of NetLink... – unstable Nov 21 '11 at 08:30
  • If you succeeded in getting this to work, you may consider copying your solution as an answer below (it's OK to answer your own question, and accept the asnwer after the two-day waiting period). I think everyone will find it useful to have this as reference. – Szabolcs Nov 21 '11 at 11:12
  • @Szabolcs: Done. Thanks for the advice. It was my first question here... – unstable Nov 21 '11 at 14:26

1 Answers1

7

The following is an explicit example which I succeeded using gfortan and gcc with the Windows system:

I found this blog Adventures in Mathlink. It is helpful with a specific example. I installed MinGW in order to use gfortran and gcc. After installation, one must set PATH in order to use gfortran and gcc without typing the path each time. A tip for adding PATH without restarting the system: After adding the PATH, open cmd, and run set PATH=C: Then close cmd, whenyou open it again, with echo %PATH%, you will see the new path list. I followed the steps in the linked blog, adapted to Windows, with the tutorial example addtwo:

The Mathematica codes writing a .bat file and running it to generate the executable

(* Write a .bat file to compile the MathLink template *.tm, FORTRAN codes *.f and 
C codes *.c files, and run it to create an executable file. *)
CreateExeF[s_String] := 
Module[{dir, libdir, bindir, BatCode, bat}, dir = NotebookDirectory[];
{libdir, bindir} = StringJoin[
  "\"", $InstallationDirectory, 
 "\\SystemFiles\\Links\\MathLink\\DeveloperKit\\Windows\\CompilerAdditions\\mldev32\\",
  #] & /@ {"lib\\", "bin\\"};
BatCode = StringJoin[
 "gfortran -c ", #, ".f -o ", #, "f.o
 gcc -c ", #, ".c -o ", #, ".o
 ",
 bindir, "mprep.exe\" ", #, ".tm -o ", #, "tm.c
 gcc -c ", #, "tm.c -o ", #, "tm.o
 gcc ", #, "tm.o ", #, ".o ", #, "f.o ",
 libdir, "ml32i3m.lib\" ", 
 "-lm -lpthread -mwindows -lstdc++ -o ", #
 ] &;
 (* write the .bat file *)
 bat = Export[FileNameJoin[{dir, # <> ".bat"}], BatCode[dir <> #], 
  "string"] &[s];
 (* run the .bat file *)
 Run[bat]]

FORTRAN codes addtwo.f

   subroutine addtwof(i,j,k)
   integer i, j, k
   k = i + j
   end

C wrapper addtwo.c

#include "mathlink.h"

int addtwo(int i, int j) 
{
  int res;
  addtwof_(&i, &j, &res);
  return res;
}

#if WINDOWS_MATHLINK

#if __BORLANDC__
#pragma argsused
#endif

int PASCAL WinMain( HINSTANCE hinstCurrent, HINSTANCE hinstPrevious, LPSTR lpszCmdLine,     int nCmdShow)
{
char  buff[512];
char FAR * buff_start = buff;
char FAR * argv[32];
char FAR * FAR * argv_end = argv + 32;

hinstPrevious = hinstPrevious; /* suppress warning */

if( !MLInitializeIcon( hinstCurrent, nCmdShow)) return 1;
MLScanString( argv, &argv_end, &lpszCmdLine, &buff_start);
return MLMain( (int)(argv_end - argv), argv);
}

#else

int main(int argc, char* argv[])
{
return MLMain(argc, argv);
}

#endif

The template file addtwo.tm is the same as the one in Todd Gayley's tutorial. For completeness, it is also given here:

:Begin:
:Function:       addtwo
:Pattern:        AddTwo[i_Integer, j_Integer]
:Arguments:      { i, j }
:ArgumentTypes:  { Integer, Integer }
:ReturnType:     Integer
:End:

:Evaluate:       AddTwo::usage = "AddTwo[i, j] gives the sum of two integer numbers i and j."
unstable
  • 441
  • 4
  • 10
  • what is your motivation to use Fortran from within Mathematica? – Rolf Mertig Nov 23 '11 at 13:13
  • @Mertig, first many many thanks to your marvelous efforts devoted to FeynCalc! To be specific, I need to calculate some decay amplitudes which contain quite a few four-point loop integrals. Then I need to plot some invariant mass distributions, and Dalitz plots. With only Mathematica, this would be extremely slow. But I want Mathematica in this case because it provides me with nice graphics. Do you have better suggestions? – unstable Nov 23 '11 at 15:48
  • @Mertig , it would be even better if the expressions can be sent to FORTRAN (through C), and then results are returned back to Mathematica... Is it feasible? – unstable Nov 23 '11 at 15:54
  • Yes. It is possible, but involved. I experimented a bit with that some time ago. This is too complicated to continue here at Stackoverflow. Send me Email directly. – Rolf Mertig Nov 23 '11 at 17:50