2
$\begingroup$

I have some polynomial e.g. $2x^2 + 3x + 4$

In Mathematica I can define this, and convert it to a string simply enough

expression = 2*x^2 + 3*x + 4
expr_string = ToString[FortranForm[expression]]

Now, I want to append to the end of every number in the string the suffix _dp e.g. 2 $\rightarrow$ 2.0_dp. I can do this simply with a Do loop as,

Do[expr_string = StringReplace[expr_string, ToString[m] -> ToString[m]<>".0_dp",{m,0,9}]

This works fine for single digit numbers, like in the example polynomial. But if I have numbers greater than 10, then this method fails e.g. 16 $\rightarrow$ 1.0_dp6.0_dp since the 1 and the 6 have both been replaced.

How can I modify this method to account for double (and upwards) digit numbers such that e.g. 16 $\rightarrow$ 16.0_dp?

Thanks

$\endgroup$
  • $\begingroup$ Can't you use a regular expression as the search string? in a normal regular expression one would have something like s/[0-9]+/*.0_dp/ $\endgroup$ – albert Aug 23 '19 at 12:17
  • 2
    $\begingroup$ Thanks for accepting my answer, but I think you were too hasty doing that. While accepting is one of the things to do after your question is answered, we recommend that users should test answers before voting and wait 24 hours before accepting the best one. That allows people in all timezones to answer your question and an opportunity for other users to point alternatives, caveats or limitations of the available answers, in this carse Carl Woll has spotted problems with my answer. $\endgroup$ – rhermans Aug 23 '19 at 15:50
  • $\begingroup$ @rhermans Ok noted. Your solution did work perfectly for my purposes though, so thanks! $\endgroup$ – user1887919 Aug 23 '19 at 16:00
3
$\begingroup$

Solution

Use the NumberString pattern.

This example works for integers only

StringReplace[
 ToString[FortranForm[ 1+10 x+123 x^2 ]]
,n:NumberString :> StringJoin[n,".0_dp"]
]
(* 1.0_dp + 10.0_dp*x + 123.0_dp*x**2.0_dp *)

Can be improved after Carl Woll's comment and snippet by J. M. this works for non-integers

StringReplace[
 ToString[
  1.1 + 10 x + 123.4 x^2
  , FortranForm
  ]
 , n : NumberString :> StringJoin[
   n
   , If[
    StringFreeQ[n, "."]
    , ".0_dp"
    , "0_dp"
    ]
   ]
]
(* 1.10_dp + 10.0_dp*x + 123.40_dp*x**2.0_dp *)

Note

expr_string = ToString[FortranForm[expression]]

Is not a valid expression for what you want. The symbol _ means Blank in Mathematica. So expr_string is actually interpreted as

Pattern[expr, Blank[string]]
$\endgroup$
  • 1
    $\begingroup$ This won't work for something like 1.1 + 10 x + 123 x^2. or 2+x2. $\endgroup$ – Carl Woll Aug 23 '19 at 15:30
  • $\begingroup$ Still doesn't work for 2+x2. Basically, I think the StringReplace approach throws away information that is present in the Mathematica expression (what is an integer, what is a symbol and what is a real), and the approach giving Integer a FortranForm format doesn't. $\endgroup$ – Carl Woll Aug 23 '19 at 15:47
  • $\begingroup$ I did in my answer to the linked question. $\endgroup$ – Carl Woll Aug 23 '19 at 15:53
  • $\begingroup$ Let us continue this discussion in chat. $\endgroup$ – Carl Woll Aug 23 '19 at 16:01
  • $\begingroup$ @user49047 I suggest you post an answer with you insights or comment on the chat. $\endgroup$ – rhermans Aug 23 '19 at 16:18
0
$\begingroup$

One can use the Replace function and use a simple pattern

Replace[expression, a : _?NumericQ :> ToString[N[a]] <> "0_dp", Infinity]

Or with FortranForm

Replace[FortranForm@N[expression], 
 a : _?NumericQ :> ToString[a] <> "0_dp", Infinity]
$\endgroup$

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