Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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!

share|improve this question
    
Something like ReplaceAll[input, x_?IntegerQ -> f[1. x]] ? –  b.gatessucks Mar 17 '13 at 9:11
    
not sure if you have this in mind, but does this work: input /. {Rational[x_, y_] :> Row[{x, ".", Blank[f]}]/Row[{y, ".", Blank[f]}], x_?NumberQ :> Row[{x, ".", Blank[f]}]}? –  kguler Mar 17 '13 at 9:28

2 Answers 2

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)"
share|improve this answer
    
@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 0: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 1:08

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

share|improve this answer
    
5/4 should be 5._f/4._f –  Orders Mar 17 '13 at 11:49
    
@Orders 5/4 is Rational not Integer. Are you aware of the difference in the context of Mathematica? –  Mr.Wizard Mar 17 '13 at 11:51
    
Yes, I don't know how to express this problem exactly. I mean , for the Rational 5/4, the integer 5 and 4 also should be changed. –  Orders Mar 17 '13 at 11:59
    
@Orders Okay, I'll start on that. –  Mr.Wizard Mar 17 '13 at 11:59
    
@Orders Please take a look. I do wonder what you're planning for this construct, and I hope it works. –  Mr.Wizard Mar 17 '13 at 12:05

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.