У меня есть часть кода, написанная в Фортране и в Matlab. Они делают точно такой же расчет, а именноКак получить точность Fortran в MatLAB
- Построить
tanh
-поле и найти ее лапласианом - Multiply некоторые термины вместе
В результате этого умножения дает матрицу, которой (4,4) th и (6,6) th я вычитаю.
- В Fortran их разность составляет ~ 1e-20
- В Matlab их разность тождественно равна нулю.
Эта проблема очень важна, поскольку я тестирую, если это число меньше нуля. Вопрос: Есть ли способ выполнить вычисления, чтобы получить такую же точность в Matlab, как в Fortran?
I список кодов ниже:
MatLAB
clear all
weights = [4./9, 1./9,1./9,1./9,1./9, 1./36,1./36,1./36,1./36];
dir_x = [ 0, 1, 0, -1, 0, 1, -1, -1, 1];
dir_y = [ 0, 0, 1, 0, -1, 1, 1, -1, -1];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CONSTANTS
length_y = 11; length_x = length_y;
y_center = 5; x_center = y_center;
densityHigh = 1.0;
densityLow = 0.1;
radius = 3.0;
c_width = 1.0;
average_density = 0.5*(densityHigh+densityLow);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for x=1:length_x
for y=1:length_y
for i=1:9
fIn(i, x, y) = weights(i)*densityHigh;
test_radius = sqrt((x-x_center)*(x-x_center) + (y-y_center)*(y-y_center));
if(test_radius <= (radius+c_width))
fIn(i, x, y) = weights(i)*(average_density - 0.5*(densityHigh-densityLow)*tanh(2.0*(radius-sqrt((x-x_center)*(x-x_center) + (y-y_center)*(y-y_center))/c_width)));
end
end
end
end
ref_density_2d = ones(length_x)*average_density;
for i=1:length_x
ref_density(:,:,i) = abs(ref_density_2d(:, i)');
end
rho = sum(fIn);
laplacian_rho = (+1.0*(circshift(rho(1,:,:), [0, -1, -1]) + circshift(rho(1,:,:), [0, +1, -1]) + circshift(rho(1,:,:), [0, -1, +1]) + circshift(rho(1,:,:), [0, +1, +1])) + ...
+4.0*(circshift(rho(1,:,:), [0, -1, +0]) + circshift(rho(1,:,:), [0, +1, +0]) + circshift(rho(1,:,:), [0, +0, -1]) + circshift(rho(1,:,:), [0, +0, +1])) + ...
-20.0*rho(1,:,:));
psi = 4.0*0.001828989483310*(rho-densityLow).*(rho-densityHigh).*(rho-ref_density) - laplacian_rho*(1.851851851851852e-04)/6.0;
psi(1,4,4)-psi(1,6,6)
FORtran
PROGRAM main
IMPLICIT NONE
INTEGER, PARAMETER :: DBL = KIND(1.D0)
REAL(KIND = DBL), DIMENSION(1:11,1:11) :: psi, rho
INTEGER :: i, j, m, ie, iw, jn, js
REAL(KIND = DBL) :: R, rhon, lapRho
INTEGER, DIMENSION(1:11,1:11,1:4) :: ni
REAL(KIND = DBL) :: kappa, kappa_6, kappa_12, kappaEf, beta, beta4
beta = 12.D0*0.0001/(1.D0*((1.0 - 0.1)**4))
kappa = 1.5D0*0.0001*1.D0/((1.0 - 0.1)**2)
!-------- Define near neighbours and initialize the density rho ----------------
DO j = 1, 11
DO i = 1, 11
! Initialize density
rho(i,j) = 1.D0
R = DSQRT((DBLE(i)-5.0)**2 + (DBLE(j)-5.0)**2)
IF (R <= (DBLE(3.0) + 1.D0)) THEN
rho(i,j) = 0.55D0 - 0.5*0.9*TANH(2.D0*(DBLE(3.0) - R)/1.D0)
END IF
!Generate neighbors array
ni(i,j,1) = i + 1
ni(i,j,2) = j + 1
ni(i,j,3) = i - 1
ni(i,j,4) = j - 1
END DO
END DO
! Fix neighbours at edges
ni(1,:,3) = 11
ni(11,:,1) = 1
ni(:,1,4) = 11
ni(:,11,2) = 1
!--------- Differential terms for the stress form of the interfacial force -----
DO j = 1, 11
DO i = 1, 11
! Identify neighbors
ie = ni(i,j,1)
jn = ni(i,j,2)
iw = ni(i,j,3)
js = ni(i,j,4)
! Laplacian of the density rho
lapRho = 4.D0*(rho(ie,j) + rho(iw,j) + rho(i ,jn) + rho(i ,js)) &
+ rho(ie,jn) + rho(ie,js) + rho(iw,jn) + rho(iw,js) - 20.D0*rho(i,j)
! Define the chemical potential Psi
psi(i,j) = 4.D0*beta*(rho(i,j) - 0.55)*(rho(i,j) - 0.1)*(rho(i,j) - 1.0) &
- kappa*lapRho/6.D0
END DO
END DO
write(*,*) psi(6,6)-psi(4,4)
END PROGRAM
Несмотря на то, информированы в противном случае в ответе на другую версию этого вопроса (HTTP : //stackoverflow.com/questions/29867870/precision-of-calculations), вы по-прежнему используете номера одной точности в своем коде Fortran. То есть «0,1» по умолчанию является реальным числом с одной точностью в Fortran (если вы не использовали параметры компилятора для настройки обычного поведения, и я уверен, что у вас его нет, есть ли у вас маленький подлец?). Это может объяснить различия, которые вы наблюдаете. На этом этапе в ваших поисках вы должны, по крайней мере, исследовать эту возможность. –
Я изменил его, поэтому он использует двойную точность, но вывод одинаков - результаты все еще различаются. Я долгое время занимался расследованием, доверяю мне ... – BillyJean
Прошу прощения, но никто не может пройти через этот код (на двух языках), запустить его и отладить.Уточните свою проблему. Узнайте первое место, где ваши результаты расходятся. В дополнение к тому, что сказал @HighPerformanceMark выше, см. Мой комментарий к вашему предыдущему вопросу - вам нужно проверить, что такие функции, как 'abs',' sqrt', 'tanh' и т. Д. (И даже деление) возвращают одинаковый результат во всех случаев. И «check» я не имею в виду просто распечатывать несколько десятичных знаков. – horchler