why is there significant double precision difference between Matlab and Mathematica?
Asked Answered
I

2

2

I created a random double precision value in Matlab by

x = rand(1,1);

then display all possible digits of x by

vpa(x,100)

and obtain:

0.2238119394911369 7971853298440692014992237091064453125

I save x to a .mat file, and import it into Mathematica, and then convert it:

y = N[FromDigits[RealDigits[x]],100]

and obtain:

0.2238119394911369 0000

Then go back to Matlab and use (copy and paste all the Mathematica digits to Matlab):

 vpa(0.22381193949113690000,100)

and obtain:

0.22381193949113689 64518061375201796181499958038330078125

Why there is significant difference between the same double precision variable?

How to bridge the gap when exchanging data between Mathematica and Matlab?

Informant answered 6/11, 2013 at 9:28 Comment(8)
If you want to "exactly" transfer "double precision" (64bit) data you should use a standard binary format, save all the issues of converting back and forth to base 10.Bondage
If you need to transfer double precision data while guaranteeing that nothing is lost, the most convenient and fastest way is to use MATLink. (Disclaimer: I'm one of the MATLink developers.) You will find that after transferring a number back and forth, there will be absolutely no difference.Nonet
hi,@Szabolcs, thank you for the suggestion. The puzzle comes from my experience when solving a nonlinear system via Mathematica and matlab/C++ in multiple precision (higher than double): Mathematica gives better and more accurate results than other "multiple precision" implementations. I want very much to understand the reason and how to avoid such issue when Mathematica is not available or when I pay more attention to efficiency since mathematica is usually slower than other implementations.Informant
hi, @Szabolcs, I also noticed in Mathemaitica, there is a "NETLink" package which also works on communication between Mathematica and Matlab, what is the difference? I not only want to transfer data between matlab and mathematica, but want to compute the original double with multiple precision in mathematica. How does Mathlink handle it? what is the difference between "N[FromDigits[RealDigits[x]],userPrecision]" and what Mathlink does? Does Mathlink support invoking Mathematica engine in Matlab script? ThanksInformant
hi @Szabolcs, I found MathLink only transfers double precision data. How can I set the Mathematica working precision of a double number from Matlab as multiple precision? The only reliable way I can imagine is still N[FromDigits[RealDigits[x]],userPrecision]...Informant
Don't confuse MATLink, which is a Mathematica package that lets you call MATLAB, with MathLink, which is Mathematica's communication protocol. Now, I thought you wanted to transfer a double precision number between MATLAB and Mathematica. This is possible with MATLink. Arbitrary precision numbers, which are part of MATLAB's symbolic toolbox, are not supported by MATLink. In you example, x is a simple double precision number. The reason why vpa(x,100) gives you that many digits is that floating point numbers are stored in binary format, not decimal. This means that even though ...Nonet
... a double precision number only has 15 or 16 usable decimal digits, the precise decimal representation of the internally stored binary number is not going to have all zeros after 15 digits, but something else, which you can mostly ignore. However, this also means that if you want to transfer the number without any loss whatsoever, you can't use decimal. You need to use a binary format. MATLink does this in the background for you. Saving to a .mat file and importing also does it, theoretically.Nonet
I suggest you read this often recommended and very popular article to gain a better understanding of how floating point numbers are stored and manipulated on computers. After you read that article, everything will be clear.Nonet
L
4

You can fix this problem by using ReadList instead of Import. I have added some demo steps below to explore displayed rounding and equality. Note the final test d == e? is False in Mathematica 7 but True in Mathematica 9, (with all the expected digits). So it looks like some precision has been added to Import by version 9. The demo uses a demo file.

Contents of demo.dat:

0.22381193949113697971853298440692014992237091064453125
"0.22381193949113697971853298440692014992237091064453125"

Exploring:-

a = Import["demo.dat"]
b = ReadList["demo.dat"]
a[[1, 1]] == a[[2, 1]]
b[[1]] == b[[2]]
a[[1, 1]] == b[[1]]
a[[1, 1]] == ToExpression@b[[2]]
b[[1]] // FullForm
c = First@StringSplit[ToString@FullForm@b[[1]], "`"]
b[[2]]
ToExpression /@ {c, b[[2]]}
d = N[FromDigits[RealDigits[a[[1, 1]]]], 100]
e = N[FromDigits[RealDigits[b[[1]]]], 100]
d == e
Larcher answered 6/11, 2013 at 10:0 Comment(1)
worth noting Import uses the file extension to determine how to process the file.Bondage
M
2

The precision is as expected for double values. A double has a 53 bit fraction, thus the precision is about 53*log(10)/log(2)=16 significant digits. You have 16 significant digits, it works as expected.

Misteach answered 6/11, 2013 at 9:52 Comment(5)
Thanks. Because I want to use the higher than double precision in Mathematica for further multiple precision computation; such conversion should be the only reliable way I can find.Informant
Using the OP's value N[x, 53] ends in a 3, but N[FromDigits[RealDigits[x]], 53] ends in 25, so I think the latter is quite good.Larcher
I also think mathematica should be superior in handling precision of numbers. Can matlab simulate the same truncating as mathematica does?Informant
The 100 is the precision argument to N, not the base argument to FromDigits.Bondage
Thx I confused the parameters. Updated answer.Misteach

© 2022 - 2024 — McMap. All rights reserved.