2

I have an expression. I want to change all the Integers to a new form. The rule is, x_Integer->x._f. But we should consider some special cases. For example,

  input = 22 +  4/5 x1 x1 x1 + (2 x2^4 + 343 Pi^4)/
  Sqrt[67 - x1 x1 x3 x3 + x2^(5/4)] + (4 x1 - x2)^(-3/2 q) + 
   Exp[-x1 x1 + 4 x2 x2 - 3 x1];

The output expression should be,

 output = 22. _f + E^(-3. _f x1 - x1^(2. _f) + 4. _f x2^(2. _f)) + (
     4. _f x1^(3. _f))/(5. _f) + (4. _f x1 - x2)^(-3. _f x3/2. _f) + (
  343. _f \[Pi]^(4. _f) + 2. _f x2^(4. _f))/Sqrt[
    67. _f + x2^(5. _f/4. _f) - x1^(2. _f) x3^(2. _f)];

So, how to construct the rule function? Thanks!

Sjoerd C. de Vries
  • 65,815
  • 14
  • 188
  • 323
Orders
  • 1,247
  • 11
  • 20

2 Answers2

3

One simple way would be to do:

     Unprotect[Integer];
Integer /: 
  Format[r_Integer, FortranForm] := (SequenceForm[r // N, "_f"]);
Protect[Integer];
Unprotect[Rational];
Rational /: 
  Format[r_Rational, 
   FortranForm] := (SequenceForm[Numerator[r] // N, "_f", "/", 
    Denominator[r] // N, "_f"]);
Protect[Rational];
Protect[Integer];
tos = ToString[#, InputForm] &;
pow[a_Symbol, b_Integer] := tos[a] <> "^" <> tos[FortranForm[b]];
pow[a_Symbol, b_] := tos[a] <> "^(" <> tos[FortranForm[b]] <> ")";
pow[a_, b_] := "(" <> tos[a] <> ")^(" <> tos[FortranForm[b]] <> ")";
input = 22 + 
   4/5 x1 x1 x1 + (2 x2^4 + 343 Pi^4)/
    Sqrt[67 - x1 x1 x3 x3 + x2^(5/4)] + (4 x1 - x2)^(-3/2 q) + 
   Exp[-x1 x1 + 4 x2 x2 - 3 x1];
StringReplace[
 ToString[FortranForm[input /. Power -> pow], InputForm], {"\\" -> "",
   "\"" -> ""}]

which gives:

"22._f + (4 x1 - x2)^((-3._f*q)/2.) + E^(-x1^2._f + 4._f*x2^2._f - \
3._f*x1) + (4._f*x1^3._f)/5. + (67 + x2^(5._f/4._f) - x1^2._f \
x3^2._f)^(-1._f/2._f)*(343._f*Pi^4._f + 2._f*x2^4._f)"
Rolf Mertig
  • 17,172
  • 1
  • 45
  • 76
  • @Mertig Thanks! If input = 22 + (23/4 x1 - x2)^(3 dd/2), then some problem happens. Is it possible to find a more simple and safe method to deal with this problem? – Orders Mar 18 '13 at 00:55
  • 1
    @Orders Yes, that is possible. Try yourself: change ToString to ToString[ ..., InputForm] and then make it all into a nice function, say ToFortran. Use Module. Document everything you do and post it here (you can edit my post if you want). – Rolf Mertig Mar 18 '13 at 01:08
1

Simplifications/reordering that will separate the numbers from the _f pattern in a way that you seem to not want will take place on your given output expression if it is evaluated.

Therefore you will need some kind of hold function here. I will use HoldForm.

input = 22 + 
   4/5 x1 x1 x1 + (2 x2^4 + 343 Pi^4)/
    Sqrt[67 - x1 x1 x3 x3 + x2^(5/4)] + (4 x1 - x2)^(-3/2 q) + 
   Exp[-x1 x1 + 4 x2 x2 - 3 x1];

input /. {
  Rational[n_, d_] :> Divide @@ HoldForm /@ {N@n f_, N@d f_},
  n_Integer :> HoldForm @@ {N[n] _f}
 }

Mathematica graphics

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371