How to use FORTRAN subroutines or functions in Mathematica?
Asked Answered
B

1

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!

Burny answered 18/11, 2011 at 16:56 Comment(13)
groups.google.com/group/comp.soft-sys.math.mathematica/… might be interesting for you.Twopence
@celtschk, that's a very interesting link. Thanks.Trellas
Ha! I'm tempted to post a similar question for COBOL :DCircumfuse
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.Whisk
This can also be useful. 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)Showdown
Searching for c and fortran questions reveals this interesting answer regarding calling conventions for using fortran with c under gcc.Trellas
This costs money but might be helpful, even though it is a different Fortran: wolfram.com/products/applications/mathcodef90Vernellvernen
The answer linked to by @Trellas 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.Policy
InterCall (also here) is an old program that allowed access to fortran routines via MathLink. Apparently some compatibly was broken in Mma V3 and I'm not sure what has happened since...Comparative
What about using NetLink as demonstrated here: groups.google.com/group/comp.soft-sys.math.mathematica/…Noctambulism
@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...Burny
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.Showdown
@Szabolcs: Done. Thanks for the advice. It was my first question here...Burny
B
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."
Burny answered 21/11, 2011 at 14:25 Comment(4)
what is your motivation to use Fortran from within Mathematica?Noctambulism
@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?Burny
@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?Burny
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.Noctambulism

© 2022 - 2024 — McMap. All rights reserved.