Tag Info

27

Here are three very simple examples to show how to call a Fortran subroutine using LibraryLink. First the subroutine is compiled into object file. Then a wrapper is used to call the Fortran subroutine and compiled into dynamic library. At the end, the library is loaded into Mathematica and run. In the examples Mathematica Version 8 is used. FIRST EXAMPLE ...

26

OK, here's a quick go using ExperimentalOptimizeExpression, which is used internally by Compile. I'm not claiming that this is a polished solution to your problem, but hopefully it can be used as a place to start. (Also, forgive any Fortran mistakes, I haven't looked at Fortran for a long time...) xx = x /. Solve[{x^2 + y^2 + z^2 == 1, x + y + z == a, x*y*...

9

This is a variant on Andre's solution (worked out before I noticed!). Anyway this takes the FORTRAN descriptor values as arguments. f77Eform[x_?NumericQ, fw_Integer, ndig_Integer] := Module[{sig, s, p, ps}, {s, p} = MantissaExponent[x]; {sig, ps} = {ToString[Round[10^ndig Abs[s]]], ToString[Abs[p]]}; StringJoin @@ Join[ ...

8

For simplicity and elegance I use Verbeia's nice Riffle-ing for continuation. While it is possible to format real numbers as requested in FortranForm I always thought that this is way too complicated in Mathematica (the code below is slightly modified from my old FeynCalc-Write2 function described here myFortrantoggle=False; (* needed to avoid recursion *) ...

8

You can get a long way to your goal using FortranForm in Mathematica and some replacement rules. ToExpression and ToString are very useful for this kind of application. (I'm giving this one a name for later use below.) step1 = FortranForm[(-48*Sqrt[6]* E^((-2*S[1, x]^2)/bx - (S[1, y]^2)/bx - (S[1, z]^2)/ bz - (S[2, x]^2)/bx - (S[2, y]^2)/bx - (S[2, ...

8

Mathematicas invocation of the compiler doesn't know about where to find the Fortran library. With a little help, however, we can point the way. Mind you this was done on a Mac but the Linux variant of Unix will behave similar. Needs["CCompilerDriver"]; CreateLibrary[{"MMA.cc", "fadd.o"}, "myadd", "Debug" -> True, "TargetDirectory" -> ".", ...

7

You can use ImportString, with the "Table" or "List" argument. See the documentation for details. ImportString["9.0E-03", "Table"] (* {{0.009}} *) or ImportString["9.0E-03", "List"] (* {0.009} *)

7

Since the CellEvaluationFunction is supposed to accept two arguments, the second being the format type, I recommend defining: GFortran[inp_, _] := . . . and then using it directly: CellEvaluationFunction -> GFortran

6

If you want to have more than one "common block," one possibility would be to use a named Context to emulate each block. For example, here I define two "blocks," common1 and common2, and define a variable x in each of them. The Module below then uses these values by prefacing the desired x with the desired Context name: common1x = 1; common2x = 2; f[x_] ...

6

V = (-G*Mn)/Sqrt[x^2 + y^2 + z^2 + cn^2]; Vx = D[V, x] /. {x -> x[1], y -> x[2], z -> x[3]}; StringReplace[ToString[Vx, FortranForm], " " -> ""]

6

data = Table[(i + j) i (i - j), {i, 1, 2}, {j, 1, 22}]; The first step is to define a function to break up each row in the data into lines not exceeded the specified maximum line length. prep[row_, fieldWidth_, lineLength_] := Module[{items = Floor[lineLength/fieldWidth]}, Partition[row, items, items, 1, {}]] The second step is to do the ...

5

here is a stab/start at it.. (at least I hope to clarify what I think you are asking..) Clear[fort, fortranreal] fort[x_Real ] := fortranreal[x] fort[x_] := x StringReplace[ ToString@MapAll[fort, FortranForm[# ]] , Shortest[ "fortranreal(" ~~ s : __ ~~ ")" ] :> s <> "_db" ] & /@ { 2 a^2 , 2. a^2, 2. 10^-20 a^3, 2. 10^51 a[...

5

Mathematica has so many output and formatting options, it's quite hard to piece all the bits together sometimes. Here's something I've managed to build by looking at the extensive documentation: formattedData = Partition[ StandardForm@ PaddedForm[ #, {16, 16}, NumberFormat -> (StringJoin[#1, "E", #3] &)] & /@ Flatten@data, 2];...

5

FortranForm is really pretty limited. You need to do something like this: A = {{1, 1. 10^7}, {2., 1}} StringJoin@{"A=reshape((/", Riffle[ ToString[FortranForm[#]] & /@ Flatten[A] , ","], "/),shape(a))"} "A=reshape((/1,1.e7,2.,1/),shape(a))" or StringJoin@{"data a/", Riffle[ ToString[FortranForm[#]] & /@ Flatten[A]...

4

The given above answer is correct, however if you are not against using undocumented functions, then InternalStringToDouble["9.0E-03"] is much faster. To demonstrate the speedup, first generate some fake data heads = ToString /@ RandomReal[{1.0000, 9.9999}, 100000, WorkingPrecision -> 5] // Quiet; exp = ConstantArray["E-", 100000]; tails = ...

4

Unfortunately I have no Mathematica access right now, but I would like to point you to some links which I think might be helpful in solving your issue: Tabular Export Formats: http://reference.wolfram.com/mathematica/guide/TabularAndSpreadsheetFormats.html Modifying the appearance of numbers: http://reference.wolfram.com/mathematica/ref/NumberForm.html

4

I find NumberForm, FortranForm ... not adequate for this problem. This is how I would do it : Treatment for one number : toEString[dat_] := If[dat == 0., "0.0000000000000000+E00", MantissaExponent[dat] // With[{mantissa = #[[1]], exponent = #[[2]]}, { If[mantissa < 0, "-", ""], "0.", ToString /@ PadRight[...

3

Eform[x_?NumericQ, ndig_Integer: 8] := Module[{u, s, p, base, exp, sign, result}, u = If[x == 0, u = 0, u = x]; {s, p} = MantissaExponent[u]; If[s != 0, {s = s*10; p = p - 1}]; base = ToString[PaddedForm[s, {ndig + 2, ndig}]]; exp = If[p >= 0, ToString[p], ToString[-1*p]]; If[StringLength[exp] < 2, exp = StringJoin["0", exp], exp = exp]; ...

3

Why not use MathCode? MathCode makes it possible to develop prototypes in the interactive Mathematica environment which can be automatically translated to fast production code in C++ or Fortran90 and, if necessary, linked to external applications.

3

Another way data = {{"(0.277336296055697,0.120000000000000E+000)"}, {"(-1.489297392708939E-002,0.340000000000000E+000)"}}; data = Flatten[StringCases[#, "(" ~~ x__ ~~ "," ~~ y__ ~~ ")"->{x, y}]&/@ a,Infinity]; Complex @@@ Partition[InternalStringToDouble[#] & /@ data, 2]

2

This changes E**argument to exp(argument): Unprotect[Power]; Power /: Format[Power[E, x_], FortranForm] := exp[x] Protect[Power]; {FortranForm[E^(3*z)], FortranForm[Exp[2*z^3]]} (* Out: {exp(3*z), exp(2*z**3)} *)

2

Yet another one: n = {{"(0.277336296055697,0.120000000000000E+000)"}, \ {"(-1.489297392708939E-002,0.340000000000000E+000)"}}; Complex @@@ ToExpression[StringReplace[Flatten[n], {"(" -> "{", ")" -> "}", "E" -> "*10^"}]] {0.277336 + 0.12 I, -0.014893 + 0.34 I}

2

Change rows and columns to taste. rows = 2; columns = 3; matr = RandomReal[{10^-12, 10^-6}, {rows, columns}]; (matr2 = Table[Row[{ "matrix(", i, ",", j, ") = ", FortranForm[matr[[i, j]]]}], {i, Length[matr]}, {j, Length[matr[[1]]]}] // Flatten) // Column

2

building on @rcollyer's answer: The main improvement here is we print the list of elements in a way that the whole list can be copied at once. (also handle arbitrary dimensions automatically ) SetAttributes[fortranprint, HoldFirst] fortranprint[array_Symbol] := fortranprint[array, SymbolName[Unevaluated[array]]]; fortranprint[array_, name_] := ...

2

There is no subtlety to this, but it works: Table[i j, {i, 5}, {j, 5}] MapIndexed[Print["a(", #2[[1]], "," , #2[[2]], ") = ", #1] &, %, {2}];

1

You can use NumberForm to customize the output. Something like the following should give you what you're after: d0Form[precision_:10] := NumberForm[#, precision, NumberFormat -> (If[(#3 == ""), Row[{#1, "d0", #3}], Row[{#1, "d", #3}]] &)] &}; Here's a test on a small matrix: matr = Table[RandomInteger[{0, 10^5}], {i, 2}, {j, 2}]...

1

There's special function for generating fortran-like forms: SetOptions[\$Output, PageWidth -> 100] FortranForm[string] And certainly you can manage string manually. To insert new strings in the string you can write something like this: string = StringJoin[ToString /@ Range[1000]]; step = 10 StringInsert[string, "&&\n&&", Range[step, ...

1

You could also use Export to export to a file directly. Or use CopyToClipboard : matr = RandomReal[{10^-12, 10^-6}, {4, 6}]; matr2 = Table[FortranForm[matr[[i, j]]], {i, 4}, {j, 6}]; matr3 = ExportString[ Flatten@Table[ "matrix(" <> ToString[i] <> "," <> ToString[j] <> ") = " <> ToString[matr2[[i, j]]], {i, Length[...

1

a = {{"(0.277336296055697,0.120000000000000E+000)"}, {"(-1.489297392708939E-002,0.340000000000000E+000)"}}; Complex @@ (ToExpression /@ {StringDrop[First@#, 1], StringTake[Last@#, 5]}) & [Flatten@StringSplit[a[[#]], ","]] & /@ Range@Length@a {0.277336 + 0.12 I, -6.04833 + 0.34 I}

Only top voted, non community-wiki answers of a minimum length are eligible