Issue correlating exp() from fortran to matlab

5 Ansichten (letzte 30 Tage)
Maxwell
Maxwell am 13 Mär. 2025
Bearbeitet: dpb am 18 Mär. 2025
Important clarification - I need Matab to match Fortran. I cannot change the Fortran code. I am working in 2018b and the function I am having an issue with is gz = 1.0 / (1+0.0247*exp(0.650*log(0.1089*re))). re is single precision in this case (Fortran). I was able to correlate 0.650*log(0.1089*re) so I know that the issue is with exp. In fortran, exp(0.650*log(0.1089*re)) = 24.09045, (24.0904521942139 if double precision), but in Matlab it is 24.0904541, (24.090454101562500 double precision). How can I modifiy the code to be the same as fortran. I have tried double() and single() everywhere but it didn't work.
The weirdest part: This code is part of a function that is used >500 times. I would say 350/500 times the results match up, but there are random stretches where it is off as described above. There is also a near similar function gx (some of the constants are different) that works 100% of the time. I made sure that I used single() and double() in the same exact spots but still got this issue.
  13 Kommentare
James Tursa
James Tursa am 15 Mär. 2025
Bearbeitet: James Tursa am 15 Mär. 2025
@Walter Roberson And that leaves a bit of wiggle room in the result. E.g.,
p = randi([-5,5],10,10);
x = sum(2.^p); % some random values that can be represented exactly in double and vpa
X = string(x');
IEEE_hex = string(num2hex(x));
table(X,IEEE_hex) % demonstrate that these are "nice" in binary floating point format
ans = 10x2 table
X IEEE_hex __________ __________________ "120.3125" "405e140000000000" "10.875" "4025c00000000000" "26.34375" "403a580000000000" "34.03125" "4041040000000000" "108.125" "405b080000000000" "56.28125" "404c240000000000" "28.8125" "403cd00000000000" "23.03125" "4037080000000000" "37.25" "4042a00000000000" "31.25" "403f400000000000"
digits 50
double(exp(vpa(x))) - exp(x)
ans = 1×10
1.0e-03 * 0 0 0 0 0 0 -0.4883 0 0 0
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
It wasn't too hard to find a value x for which exp(x) did not give a result that was correctly rounded "as if the calculation were performed in infinite precision". This is unlike the IEEE requirement for the +, -, *, and / operations which do have this strict requirement.
exp_vpa_x = string(num2hex(double(exp(vpa(x)))));
exp_x = string(num2hex(exp(x)));
table(exp_vpa_x,exp_x)
ans = 10x2 table
exp_vpa_x exp_x __________________ __________________ "4ac7d28912b900dc" "4ac7d28912b900dc" "40e9ccd7d3d55bc5" "40e9ccd7d3d55bc5" "42501110262b98ea" "42501110262b98ea" "43011c005aae8303" "43011c005aae8303" "49afcf51cc64d9fe" "49afcf51cc64d9fe" "4502564116ff8878" "4502564116ff8878" "4287b6b72fba0d83" "4287b6b72fba0d84" "4202ba2f9c4855b1" "4202ba2f9c4855b1" "434abae41f425f94" "434abae41f425f94" "42c0f63a92073371" "42c0f63a92073371"
The 7th value above differs by 1 ULP. A different library using a different algorithm meeting the same 1 ULP standard as MATLAB could get a different result. Hence the advice to not rely on exact comparisons for library functions.
dpb
dpb am 15 Mär. 2025
+1 @James Tursa for elegant exposition...

Melden Sie sich an, um zu kommentieren.

Antworten (0)

Produkte


Version

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by