Я делаю расчет на Фортране для переменной двойной точности, и после расчета переменная получает значение -7.217301636365630e-24
.
Однако, когда я делаю те же вычисления в Matlab, переменная просто получает значение 0
. Есть ли способ повысить точность MatLAB при выполнении вычислений, чтобы я также мог получить что-то порядка 7e-24
?
В идеале это было бы то, что я мог бы применить ко всем вычислениям в скрипте, а не только к одной переменной. Что-то похожее на использование format long
.
Для меня такая точность имеет решающее значение, поскольку мне нужно определить, действительно ли переменная отрицательна или нет.
Я добавил код. Он довольно длинный, но я не мог его урезать, не отбрасывая переменные и их точность. Последний член, Ax(i,:,:)
, я хотел бы иметь очень высокой точностью. Таким образом, важные вещи появляются только в последней строке.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CONSTANTS
clc
clear all
sym_weight = [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];
ly = 11; lx = ly;
xC = 5; yC=xC;
density_high = 1.0;
density_low = 0.1;
radius = 2;
interface_w = 1;
sigma_st = 0.0001;
beta = 12*sigma_st/(interface_w*(density_high-density_low)^4);
kappa = 1.5*sigma_st*interface_w/(density_high-density_low)^2;
saturated_density = 0.5*(density_high+density_low);
for x=1:lx
for y=1:ly
for i=1:9
fIn(i, x, y) = sym_weight(i)*density_high;
gIn(i, x, y) = 3*sym_weight(i);
test_radius = sqrt((x-xC)^2 + (y-yC)^2);
if(test_radius <= (radius+interface_w))
fIn(i, x, y) = sym_weight(i)*( saturated_density - 0.5*(density_high-density_low)*tanh(2*(radius-sqrt((x-xC)^2 + (y-yC)^2))/interface_w) );
end
end
end
end
density_2d = ones(lx)*saturated_density;
for i=1:lx
density_aux(:,:,i) = abs(density_2d(:, i)');
end
density_local = sum(fIn);
L_density_local = (+1.0*(circshift(density_local(1,:,:), [0, +1, +1]) + circshift(density_local(1,:,:), [0, -1, +1]) + circshift(density_local(1,:,:), [0, +1, -1]) + circshift(density_local(1,:,:), [0, -1, -1])) + ...
+4.0*(circshift(density_local(1,:,:), [0, +1, +0]) + circshift(density_local(1,:,:), [0, -1, +0]) + circshift(density_local(1,:,:), [0, +0, +1]) + circshift(density_local(1,:,:), [0, +0, -1])) + ...
-20.0*density_local(1,:,:));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
chem_pot = 4*beta*(density_local-density_low).*(density_local-density_high).*(density_local-density_aux) - kappa*L_density_local/6;
for i=3
Ax(i,:,:) = (+circshift(chem_pot(1,:,:), [0,-2*dir_x(i),-2*dir_y(i)]) - chem_pot(1,:,:));
end
format long
повлияет только на отображение числа, а не на его значение. Я предполагаю, что вы уже сделали это, и он все еще отображает0
. - person beaker   schedule 25.04.2015your_variable=double(your_variable)
будет следить за тем, чтобы они считались двойными (но это действительно тип по умолчанию, если вы не укажете что-то еще) - person Hoki   schedule 25.04.2015abs
,sqrt
,tanh
и т. д. (и даже деление), возможно, не будут давать идентичный вывод с плавающей запятой для одних и тех же входных данных на разных языках. Суммирование членов в другом порядке также может привести к другому результату. Я также предполагаю, что вы подтвердили, что эта проблема не связана с ошибкой ни в одной из версий. - person horchler   schedule 25.04.2015Ax
, некоторые элементыAx
округляются до 0 в MatLAB, но имеют значения порядка1e-24
в Фортране. Кроме того, просто невозможно, чтобы записьAx
была равна 0, если подумать о том, как она устроена математически. Маленький да, но не 0. - person BillyJean   schedule 25.04.2015i=3
, поэтому он должен сместиться - person BillyJean   schedule 25.04.2015density
, после этого я получаю только 9 цифр. Если я использую, например,vpa(density(1,1,1), 25)
, он добавляет 25 цифр. Как я могу сделать 25 цифр по умолчанию для всех переменных в скрипте? - person BillyJean   schedule 25.04.2015i
. Тем не менее, если вы посмотрите на первый член двух ваших членов (тот, что с циркульным сдвигом, и прямой), там много равных членов (я насчитал 49). Поэтому, если эти термины должны быть разными, точность теряется не во время последнего вычитания, а раньше. Я не знаком сvpa
, но полагаю, вам придется объявлять все важные переменные по отдельности. - person Hoki   schedule 25.04.2015