2014-02-21 94 views
1

我在MATLAB中有一個代碼,它使用的數字非常小,例如,我的值大約在10^{ - 25}的數量級,但是當MATLAB進行計算時,這些值本身被舍入爲0。 ,我不是指format顯示這些額外的小數,而是數字本身更改爲0.我認爲原因是因爲默認情況下,MATLAB在計算小數點後最多使用15位數。我怎樣才能改變這一點,使得非常小的數字在計算中保留下來?如何阻止MATLAB將極小值舍入爲0?

編輯:

我的代碼如下:

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是用於針對碼我的數據文件。運行代碼後(應該花費大約一分半時間才能完成運行),變量x中的行11顯示0(即使在雙擊後檢查其實際值),但不應該。

+1

Matlab不會將這些較小的_numbers_更改爲0.嘗試鍵入例如'x = 10^-60'並檢查「x」是否具有正確的值。但是,小的_differences_會舍入到0:例如,'x = 1 + 10^-25'會給出'1',因爲您指出的原因。 –

+0

是的,實際上這就是問題所在,我用我的代碼編輯了我原來的帖子,任何建議都會有幫助。 – user3184733

+0

縮放數字,使它們更大。 EG使用分子=(b(i,1) - b0)./ b0 –

回答

5

您遇到的問題是因爲IEEE standard for floating points無法區分您的數字與零,因爲它們沒有使用足夠的位。

看看約翰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的高精度浮點數之一,在分配它們並乘以pi時稱爲small_hpf

>> 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