4

Suppose I have a very long string

x=2*g*o*p*s*v-2*B*g*o*p*s*v*w+2*a*c*g*m*o*p*s*v+2*c*g*m*o*p*s*v*B-2*a*c*g*m*o*p*s*v*B+3*g*m*o*p*s*v*B-3*B*g*m*o*p*s*v*w*B+m*w**2*B +5*a*c*g*m**2 +o*p*s*v*B -a*c*m**2*w**2*B +c*g*m**2*o*p*s*v*B* - 3*a*c*g*m*o*p*s*v*+c*m**2-w**2*B-a*c*m**2-w**2*B....)

etc that goes on for almost 1000 lines. When exported to a .txt file, the file is >100MB. I want to use the expression in Fortan and Fortan will not accept lines greater than 100 characters or so.

To the string x, is it possible to insert a linebreak every 100 characters and insert && at the end of each line and at the beginning of the next line?

  • 3
    StringInsert[str, "&&\n&&", #] &@Range[100, StringLength@str, 100] – Öskå Mar 10 '14 at 16:51
  • 1
    @Öskå Why, in the name of God, why do you not put that up as an answer? It really does not require any more elaboration than an intro line to make up for the minimum amount of characters. This is a perfectly acceptable solution! – István Zachar Mar 10 '14 at 17:05
  • 1
    @IstvánZachar Because it's in the documentation and can easily be found? I don't know :( – Öskå Mar 10 '14 at 17:10
  • 1
    @Öskå Thanks and pardon me for my zeal! Do not forget: each reputation point brings you closer to the 3K privilege of voting to close as "answer can be easily found in the documentation". It's worth fighting for! :) – István Zachar Mar 10 '14 at 18:55
  • @IstvánZachar My answering rate is so low that I plan to reach the 3K in about 2 years B-) – Öskå Mar 10 '14 at 18:59
  • @Öskå Well, one more answer in the bag now :) Keep up the good work! – István Zachar Mar 10 '14 at 19:08
  • FWIW modern fortran (f90+) wants one ampersand at the end of the line and only optionally needs one at the beginning of the continued line. I Don't know if the doubles hurt, but no need to make it more ugly than it needs to be. – george2079 Mar 14 '14 at 21:26
  • Add as well, when you are done you are liable to run into a (compiler dependent) limit on the number of continuation lines. You may need to set a compiler flag to allow longer lines so you need less continuations. – george2079 Mar 14 '14 at 21:40
  • might want to look at this as well..http://mathematica.stackexchange.com/questions/17736/how-can-i-get-mathematica-to-produce-better-fortran-code – george2079 Mar 14 '14 at 23:40

3 Answers3

5
x = "2*g*o*p*s*v-2*B*g*o*p*s*v*w+2*a*c*g*m*o*p*s*v+2*c*g*m*o*p*s*v*B-2*a*c*g
     *m*o*p*s*v*B+3*g*m*o*p*s*v*B-3*B*g*m*o*p*s*v*w*B+m*w**2*B+5*a*c*g*m**2+o
     *p*s*v*B-a*c*m**2*w**2*B+c*g*m**2*o*p*s*v*B*-3*a*c*g*m*o*p*s*v*+c*m**2-w**2
     *B-a*c*m**2-w**2*B....)"

StringInsert[x, "&&\n&&", #] &@Range[100, StringLength@x, 100]

giving you what you want.

Öskå
  • 8,587
  • 4
  • 30
  • 49
3

An adaptation from the documentation for PageWidth. It has the advantage of breaking between words, so you don't accidentally split a symbol name.

SeedRandom[1];
expression = 
 RandomInteger[{1, 3}, Length@#].ToExpression[#] &@ CharacterRange["a", "k"]
(*
  2 a + b + 2 c + 2 d + e + f + g + 2 h + i + j + k
*)

string = "x = " <> ToString@FortranForm[Expand[expression^3]];

file1 = $TemporaryPrefix <> "test1.txt";
stream = OpenWrite[file1, PageWidth -> 80];
Write[stream, TraditionalForm@string];
Close[stream];

StringReplace[Import[file1], "\\\n" -> "&&\n&&"]
(*
  x = 8*a**3 + 12*a**2*b + 6*a*b**2 + b**3 + 24*a**2*c + 24*a*b*c + 6*b**2*c + &&
  &&24*a*c**2 + 12*b*c**2 + 8*c**3 + 24*a**2*d + 24*a*b*d + 6*b**2*d + 48*a*c*d + &&
  &&24*b*c*d + 24*c**2*d + 24*a*d**2 + 12*b*d**2 + 24*c*d**2 + 8*d**3 + 12*a**2*e + &&
  ...
*)

For some reason, using FortranForm as the output format does not produce the OP's desired formatting. (I don't know Fortran.) Otherwise, one might be able to use

stream = OpenWrite[file1, PageWidth -> 80, FormatType -> FortranForm];
Michael E2
  • 235,386
  • 17
  • 334
  • 747
  • 1
    I just checked the double &'s are not legal, should be: "&\n" or "&\n&". Fortran would not mind if you broke in the middle of a symbol name by the way, but it is much more readable if you avoid it. – george2079 Mar 14 '14 at 21:35
  • @george2079 Thanks. I would change it, but the OP asked for &&. FortranForm puts several spaces, followed by a hyphen -, followed by more spaces at the beginning of the line. No & at the end of the lines. That looks wrong to me, based on what I skimmed from the web. – Michael E2 Mar 14 '14 at 21:41
  • FortranForm is giving you old f77 format : nothing at the end of the line then 5 spaces and "any" character in the 6th col. An ampersand is a better choice than a hyphen IMO.. "\n &" – george2079 Mar 14 '14 at 21:49
  • @george2079 Yes, my mistake it should be a single &. – user3401348 Mar 27 '14 at 15:51
2

Another solution but could be slower for such a big string. Worth to try:

StringJoin @@ Riffle[Characters@longstring, "&&\n&&", 100]
Kuba
  • 136,707
  • 13
  • 279
  • 740