如何阻止MATLAB将极小值舍入为0?

时间:2014-02-21 17:02:20

标签: matlab

我在MATLAB中有一个代码,它使用非常小的数字,例如,我的值大约为10 ^ { - 25},但是当MATLAB进行计算时,值本身会舍入为0。注意,我不是指format来显示这些额外的小数,而是将数字本身更改为0.我认为原因是因为默认情况下,MATLAB在小数点后使用最多15位数字计算。如何更改此值,以便保留非常小的数字,因为它们在计算中?

编辑:

我的代码如下:

clc;
clear;

format long;

% Import data
P = xlsread('Data.xlsx', 'P');
d = xlsread('Data.xlsx', 'd');
CM = xlsread('Data.xlsx', 'Cov');


Original_PD = P;                       %Store original PD
LM_rows = size(P,1)+1;                           %Expected LM rows
LM_columns = size(P,2);                 %Expected LM columns
LM_FINAL = zeros(LM_rows,LM_columns);    %Dimensions of LM_FINAL

for ii = 1:size(P,2)

P = Original_PD(:,ii);
% c1, c2, ..., cn, c0, f
interval = cell(size(P,1)+2,1);

for i = 1:size(P,1)
    interval{i,1} = NaN(size(P,1),2);
    interval{i,1}(:,1) = -Inf;
    interval{i,1}(:,2) = d;

    interval{i,1}(i,1) = d(i,1);
    interval{i,1}(i,2) = Inf;
end
interval{i+1,1} = [-Inf*ones(size(P,1),1) d];
interval{i+2,1} = [d Inf*ones(size(P,1),1)];

c = NaN(size(interval,1),1);
for i = 1:size(c,1)
    c(i,1) = mvncdf(interval{i,1}(:,1),interval{i,1}(:,2),0,CM);
end

c0 = c(size(P,1)+1,1);
f = c(size(P,1)+2,1);
c = c(1:size(P,1),:);
b0 = exp(1);
b = exp(1)*P;

syms x;

eqn = f*x;
for i = 1:size(P,1)
    eqn = eqn*(c0/c(i,1)*x + (b(i,1)-b0)/c(i,1));
end

eqn = c0*x^(size(P,1)+1) + eqn - b0*x^size(P,1);

x0 = solve(eqn);
x0 = double(x0);

for i = 1:size(x0)
    id(i,1) = isreal(x0(i,1));
end

x0 = x0(id,:);
x0 = x0(x0 > 0,:);

clear x;

for i = 1:size(P,1)
    x(i,:) = (b(i,1) - b0)./(c(i,1)*x0) + c0/c(i,1);
end

% x = [x0 x1 ... xn]
x = [x0'; x];
x = x(:,sum(x <= 0,1) == 0);

% lamda
lamda = -log(x);
LM_FINAL(:,ii) = lamda;
end

问题在于此步骤:

 for i = 1:size(P,1)
        x(i,:) = (b(i,1) - b0)./(c(i,1)*x0) + c0/c(i,1);
end

“差异”非常接近0.如何在此步骤中停止此舍入?

例如,当i = 10时,我有以下值:

b_10 = 0.006639735483297
b_0 = 2.71828182845904
c_10 = 0.000190641848119641
c_0 = 0.356210110252579
x_0 = 7.61247930625269

在进行计算之后,我们得到:-1868.47805854794 + 1868.47805854794,它产生-2.27373675443232E-12的差异,由MATLAB舍入为0。

编辑2:

Here是我的数据文件,用于代码。运行代码后(大约需要一分半钟才能完成运行),变量11中的行x显示0(即使双击后检查它的实际值),当它应该'吨。

1 个答案:

答案 0 :(得分:5)

您遇到的问题是因为IEEE standard for floating points无法将您的数字与零区分开来,因为它们没有使用足够的位数。

看看John D'Errico的Big Decimal ClassVariable Precision Integer Arithmetic。另一种选择是使用Big Integer Class from Java,但如果您不熟悉使用Java and othe rexternal libraries in MATLAB,那可能会更具挑战性。

您能举例说明您使用1e-25并获得零的计算吗?这是我得到的一个名为small_num的浮点和John的高精度浮点数之一,在分配它们并乘以small_hpf时称为pi

>> small_num = 1e-25

small_num =

   1.0000e-25

>> small_hpf = hpf(1e-25)
small_hpf =
1.000000000000000038494869749191839081371989361591338301396127644e-25
>> small_num * pi

ans =

   3.1416e-25

>> small_hpf * pi
ans =
3.141592653589793236933163473501228686498684350685747717239459106e-25