2

In MMA I have a 2d matrix whose each entry is a irrational number(in fraction format in MMA). Say:

{{-4,           -(2/Sqrt[5]),  0]},
 {-(4/Sqrt[20]), -4,            -Sqrt[2]},
 {1,            0,             0}} 

Now I would like to convert it into decimals and save as much precision as possible before feeding it into C++.

I learnt that 16 significant decimal places is the limit of double precision in C++. So I would like to convert the matrix above into one with scientific notation with entries like:

1.1234567890123456E10

or

1.1234567890123456E-10

Then I can make the best use of 16 digits in the double precision and give the matrix directly to C++.

Here comes the question:

  1. how could I convert the fractions into the "E" notation?

and

  1. save the matrix in a plain text file friendly to the Eigen Library I'm using? See the format here: Example
matrix << 1,0,1,0,
          1,0,1,0,
          1,0,1,0,

I have tried ScientificForm but what was exported was like:

ScientificForm[-0.816496580927726]...

What if I just need the numbers in E notation?

James LT
  • 303
  • 2
  • 11

1 Answers1

2

You can use NumberFormat option in ScientificForm to do this. For example

cformat[x_, numDigts_] := 
 ToString[
   ScientificForm[x, numDigts, NumberFormat -> (Row[If[#3 == "", {#1}, {#1, "E", #3}]] &)]]

then

cformat[1.2345678*^-10, 4]
(* "1.235E-10" *)

However, since your data is all in the range of 0 to 10, there would be no "E" in the results:

data = {{-4, -(2/Sqrt[3]), 0}, {-(4/Sqrt[3]), -4, -Sqrt[2]}, {1, 0, 0}};
StringRiffle[StringRiffle[#, "\t"] & /@ Map[cformat[#, 10] &, N@data, {-1}], "\n"]

(*
-4. -1.154700538    0.
-2.309401077    -4. -1.414213562
1.  0.  0.
*)

If you like to make the format line up together nicely and always have the "E", here is a version modified from george2079's answer:

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[Table[" ", {fw - ndig - 7}], 
    If[x < 0, "-", " "], {"0."}, {sig}, 
    Table["0", {ndig - StringLength[sig]}], {"E"}, 
    If[p < 0, {"-"}, {"+"}], Table["0", {2 - StringLength[ps]}], {ps}]]

toCformat2D[A_, numDigts_: 8] := Module[{lth, lineToString},
  lth = Length[A];
  lineToString[ls_] := StringRiffle[ToString /@ f77Eform[#, 2*numDigts, numDigts] & /@ ls, "\t"];
  StringRiffle[Table[lineToString[A[[n]]], {n, 1, lth}], "\n"]
  ]



toCformat2D[data, 10]
(* 
  "-0.4000000000E+01       -0.1154700538E+01        0.0000000000E-307
   -0.2309401077E+01       -0.4000000000E+01       -0.1414213562E+01
    0.1000000000E+01        0.0000000000E-307       0.0000000000E-307" 
*)
xslittlegrass
  • 27,549
  • 9
  • 97
  • 186