1
$\begingroup$

I have a C++ program that outputs a file containing a list of floating point numbers, which I want to read into Mathematica. The file looks like:

a = { 0.047295, 2.9162e-5, -8.3425e+12 };

and so on. I then write in Mathematica:

<<"myfile.txt"

to import the file. The problem is that Mathematica doesn't understand correctly the numbers in scientific notation.

Is there an easy way to fix this problem, either on the C++ side or on the Mathematica side?

$\endgroup$
  • 3
    $\begingroup$ Why are you writing the file in this format? You seem to want to write Mathematica syntax, but then get it wrong because 1e2 is not valid in Mathematica. It would be much easier if you wrote some common file format that Mathematica (and other systems) already support, such as a simply whitespace separated table (for Import[..., "Table"]) or JSON (which is easier to generate than the format you show here). It seems to me that you are making life difficult for yourself for no good reason. $\endgroup$ – Szabolcs May 18 '17 at 10:30
  • $\begingroup$ First of all, welcome to Mma SE Make the most of Mma.SE and take the tour now. Help us to help you, write an excellent question. Edit if improvable, show due diligence, give brief context, include minimal working examples of code and data in formatted form. As you receive give back, vote and answer questions, keep the site useful, be kind, correct mistakes and share what you have learned. $\endgroup$ – rhermans May 18 '17 at 10:35
  • $\begingroup$ Ok. What if you want something more complicated than a simple table? Say a = {{1, {1.1, 1.2, 1.3}}, {2, {2.1, 2.2, 2.3}}} etc. I think ​for this you do need Mathematica syntax. $\endgroup$ – Gabriel Nivasch May 18 '17 at 10:49
  • $\begingroup$ @GabrielNivasch You can use JSON. There are many easy to use JSON libraries for C++. If you don't want to use those, you can also write JSON "manually" more easily than dealing with Mathematica's exponent notation. What advantage does your format have then? I think none at all. Only disadvantages. $\endgroup$ – Szabolcs May 18 '17 at 11:01
  • 1
    $\begingroup$ I didn't know about JSON. If JSON can handle nested lists as I wrote above, and if Mathematica can easily import JSON with numbers in scientific notation, then feel free to add that as an answer. When I bumped into this problem, I searched this site but couldn't find anything that helps. That's why I came up with that frexp() hack. $\endgroup$ – Gabriel Nivasch May 18 '17 at 11:12
4
$\begingroup$

I recommend that you write your data into the JSON format instead of Mathematica syntax. If you already have C++ code to generate the output you show, it will be easier to modify this code to produce JSON than to deal with Mathematica's *^ exponent notation. JSON uses the same exponent notation as C, and supports arbitrary nesting of data.

As a plus, your output files will be in a standard format that can be read not only by Mathematica, by almost all other scientific computing systems.

Finally, there are many easy-to-use, extensible JSON libraries for C++. Many of them are header-only, so you can include them in your project without much fuss. Many support directly writing STL containers.

Instead of

a = { 0.047295, 2.9162e-5, -8.3425e+12 };

output

{"a": [ 0.047295, 2.9162e-5, -8.3425e+12 ]};

Then import as "RawJSON" for easy post-processing.

ImportString["{\"a\":[0.047295,2.9162e-5,-8.3425e+12]}", "RawJSON"]
(* <|"a" -> {0.047295, 0.000029162, -8.3425*10^12}|> *)

Always prefer standard formats to custom ones, unless you have a really really good reason to invent your own format and write your own importers and exporters.

$\endgroup$
  • $\begingroup$ Does JSON support nested lists? Like a = {{1, {1.1, 1.2, 1.3}}, {2, {2.1, 2.2, 2.3}}} $\endgroup$ – Gabriel Nivasch May 18 '17 at 11:24
  • 1
    $\begingroup$ @GabrielNivasch I thought it was clear from the link I included that it does ... or you could have tried it: ImportString["[1, [2,3]]", "RawJSON"] $\endgroup$ – Szabolcs May 18 '17 at 11:56
  • $\begingroup$ How do I import a RawJSON file? I tried Import["C:\\Users\\...\\myfile.txt","RawJSON"] and I get the error "The Import element "RawJSON" is not present when importing as "Text."" $\endgroup$ – Gabriel Nivasch May 18 '17 at 16:48
  • $\begingroup$ @GabrielNivasch JSON files normally have the .json extension. But the wrong extension is not usually a problem with Import. It is more likely that you have an old version of Mathematica that does not support the RawJSON import format. Check the documentation for RawJSON. If it is not present, you can use the JSON import format. This produces a rule list instead of nested associations, which is slightly less convenient to work with. If you prefer associations, take a look here. $\endgroup$ – Szabolcs May 18 '17 at 17:10
  • $\begingroup$ I have Mathematica 10 $\endgroup$ – Gabriel Nivasch May 18 '17 at 17:12
3
$\begingroup$

Actually there are some problems with importing FP numbers via string literal in Mathematica. I tested 11 different methods against the specialized test collection and every single one of them failed.

So to make sure the import is executed perfectly correct I wrote my own util. method that passes all the tests, described it here and made it publicly available here.

Although, I'll have to check these findings against the latest version of Mathematica.

$\endgroup$
  • $\begingroup$ Looks like a nice implementation. One small improvement you could make is add a second argument to Throw. $\endgroup$ – user21 May 19 '17 at 13:24
2
$\begingroup$

A quick hack on the C++ side is to break up the floating-point numbers into mantissa and exponent using the frexp() function, as follows:

void my_out_double(double d, ostream &s)
{
   int exp;
   double fr;
   fr = frexp(d, &exp);
   s << fr << "*2^" << exp;
}

Using this, the above file will look like:

a = {0.75672*2^-4, 0.95558*2^-15, -0.948432*2^43};

which Mathematica will have no problem reading correctly.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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