Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab NaN和Inf问题_Matlab_Nan_Infinity - Fatal编程技术网

Matlab NaN和Inf问题

Matlab NaN和Inf问题,matlab,nan,infinity,Matlab,Nan,Infinity,因此,我在Matlab中实现EM算法,但我的矩阵很快就会被NaN和Inf值所污染。我认为这可能是由矩阵反转引起的,但我不确定这是唯一的原因 代码如下: function [F, Q, R, x_T, P_T] = em_algo(y, G) % y_t = G_t'*x_t + v_t 1*1 = 1*p p*1 % x_t = F*x_t-1 + w_t p*1 = p*p p*1 % G is T*p p = size(G,2); % p = n

因此,我在Matlab中实现EM算法,但我的矩阵很快就会被
NaN
Inf
值所污染。我认为这可能是由矩阵反转引起的,但我不确定这是唯一的原因

代码如下:

function [F, Q, R, x_T, P_T] = em_algo(y, G)
    % y_t = G_t'*x_t + v_t    1*1 = 1*p p*1
    % x_t = F*x_t-1 + w_t     p*1 = p*p p*1
    % G is T*p
    p = size(G,2); % p = nb assets ; G = T*p
    q = size(y,2); % q = nb observations ; y = T*q
    T = size(y,1); % y is T*1
    F = eye(p); % = Transition matrix  p*p 
    Q = eye(p); % innovation (v) covariance matrix p*p
    R = eye(q); % noise (w) covariance matrix q x q
    x_T_old = zeros(p,T);
    mu0 = zeros(p,1);
    Sigma = eye(p); % Initial state covariance matrix p*p
    converged = 0;
    i = 0;
    max_iter = 60; % only for testing purposes
    while ~converged
        if i > max_iter
            break;
        end
        % E step = smoothing
        fprintf('Iteration %d\n',i);
        [x_T,P_T,P_Tm2] = smoother(G,F,Q,R,mu0,Sigma,y);
        %x_T

        % M step 
        A = zeros(p,p);
        B = zeros(p,p);
        C = zeros(p,p);
        R = eye(q);

        for t = 2:T % eq (9) in EM paper
            A = A + (P_T(:,:,t-1) + (x_T(:,t-1)*x_T(:,t-1)'));
        end

        for t = 2:T % eq (10)
            %B = B + (P_Tm2(:,:,t-1) + (x_T(:,t)*x_T(:,t-1)'));
            B = B + (P_Tm2(:,:,t) + (x_T(:,t)*x_T(:,t-1)'));
        end

        for t = 1:T %eq (11)
            C = C + (P_T(:,:,t) + (x_T(:,t)*x_T(:,t)'));
        end    

        F = B*inv(A); %eq (12)
        Q = (1/T)*(C - (B*inv(A)*B')); % eq (13)  pxp 

        for t = 1:T
            bias = y(t) - (G(t,:)*x_T(:,t));
            R = R + ((bias*bias') + (G(t,:)*P_T(:,:,t)*G(t,:)'));
        end
        R = (1/T)*R;

        if i>1            
            err = norm(x_T-x_T_old)/norm(x_T_old);
            if err < 1e-4
                converged = 1;
            end            
        end  
        x_T_old = x_T;
        i = i+1;
    end
    fprintf('EM algorithm iterated %d times\n',i);
end
NaN
s和
Inf
s在第8次迭代前后开始弹出

我猜在那里的某个地方,我正在用我的矩阵做一些不神圣的事情,但我真的不知道哪里出了问题。我相信你的专业知识

提前谢谢你的帮助


罗迪: 下面是我如何生成数据的(它还不是“真实世界”的数据,只是生成一些测试数据以检查没有任何错误):

丹: 你说得对。我确实缺乏真正理解公式是如何推导出来的数学背景。我知道这没用,但我不确定我暂时能补救/


罗迪:是的,我确实得出了同样的结论。但我真的不知道是什么让事情变得如此糟糕

以下是该报的链接:


平滑器的公式都在附录的最后。谢谢你抽出时间

由于用户似乎已将答案插入到他的问题中,我将在此处发布:

如@Rody所述,问题的原因是使用
inv
创建了
NaN
Inf


用户通过使用
pinv
来“解决”这一问题。

您可以而且应该在问题中直接嵌入代码。您可能希望使用
dbstop运行它,如果是naninf
,这样您就可以快速看到它第一次发生的时间并追溯它发生的原因。在编辑您的问题时,我看到一个
inv(A)
弹出几次。决不,决不,决不,决不直接使用
inv()!!它速度慢、不准确、不稳定等。请使用
LU
分解和/或反斜杠运算符。您能给出输入
y
G
的示例吗?Dennis的建议非常好。但是,代码中的注释“inv()导致出现NaN值,pinv似乎解决了问题”是一个很大的危险信号,表明您并不真正理解此代码和/或算法在做什么(这没有错,我们都会遇到!)。所以我的建议是退一步想想这个算法应该做什么,以及矩阵求逆的目的是什么。解决这个问题可能只需要一些额外的思考。
function [x_T, P_T, P_Tm2] = smoother(G,F,Q,R,mu0,Sigma,y)
    % G is T*p
    p = size(mu0,1); % mu0 is p*1
    T = size(y,1); % y is T*1
    J = zeros(p,p,T);
    K = zeros(p,T); % gain matrix
    x = zeros(p,T);
    x(:,1) = mu0;
    x_m1 = zeros(p,T);
    x_T = zeros(p,T); % x values when we know all the data
    % Notation : x = xt given t ; x_m1 = xt given t-1 (m1 stands for minus
    % one)
    P = zeros(p,p,T);% array of cov(xt|y1...yt), eq (6) in Shumway & Stoffer 1982
    P(:,:,1) = Sigma;
    P_m1 = zeros(p,p,T); % Same notation ; = cov(xt, xt-1|y1...yt) , eq (7)
    P_T = zeros(p,p,T);
    P_Tm2 = zeros(p,p,T); % cov(xT, xT-1|y1...yT)

    for t = 2:T %starts at t = 2 because at each time t we need info about t-1
        x_m1(:,t) = F*x(:,t-1); % eq A3 ; pxp * px1 = px1
        P_m1(:,:,t) = (F*P(:,:,t-1)*F') + Q; % A4 ; pxp * pxp = pxp

        if nnz(isnan(P_m1(:,:,t)))
            error('NaNs in P_m1 at time t = %d',t);
        end
        if nnz(isinf(P_m1(:,:,t)))
            error('Infs in P_m1 at time t = %d',t);
        end

        K(:,t) = P_m1(:,:,t)*G(t,:)'*pinv((G(t,:)*P_m1(:,:,t)*G(t,:)') + R); %A5 ; pxp * px1 * 1*1 = p*1
        %K(:,t) = P_m1(:,:,t)*G(t,:)'/((G(t,:)*P_m1(:,:,t)*G(t,:)') + R); %A5 ; pxp * px1 * 1*1 = p*1

        % The matrix inversion seems to generate NaN values which quickly
        % contaminate all the other matrices. There is no warning about
        % (close to) singular matrices or whatever. The use of pinv()
        % instead of inv() seems to solve the problem... but I don't think
        % it's the appropriate way to deal with it, there must be something
        % wrong elsewhere

        if nnz(isnan(K(:,t)))
            error('NaNs in K at time t = %d',t);
        end


        x(:,t) = x_m1(:,t) + (K(:,t)*(y(t)-(G(t,:)*x_m1(:,t)))); %A6
        P(:,:,t) = P_m1(:,:,t) - (K(:,t)*G(t,:)*P_m1(:,:,t)); %A7
    end

    x_T(:,T) = x(:,T);
    P_T(:,:,T) = P(:,:,T);

    for t = T:-1:2 % we stop at 2 since we need to use t-1
        %P_m1 seem to get really huge (x10^22...), might lead to "Inf"
        %values which in turn might screw pinv()

        %% inv() caused NaN value to appear, pinv seems to solve the issue

        J(:,:,t-1) = P(:,:,t-1)*F'*pinv(P_m1(:,:,t)); % A8 pxp * pxp * pxp  
        %J(:,:,t-1) = P(:,:,t-1)*F'/(P_m1(:,:,t)); % A8 pxp * pxp * pxp  
        x_T(:,t-1) = x(:,t-1) + J(:,:,t-1)*(x_T(:,t)-(F*x(:,t-1))); %A9  % Becomes NaN during 8th iteration!
        P_T(:,:,t-1) = P(:,:,t-1) + J(:,:,t-1)*(P_T(:,:,t)-P_m1(:,:,t))*J(:,:,t-1)'; %A10

        nans = [nnz(isnan(J)) nnz(isnan(P_m1)) nnz(isnan(F)) nnz(isnan(x_T)) nnz(isnan(x_m1))];  
        if nnz(nans)
            error('NaN invasion at time t = %d',t);
        end
    end

    P_Tm2(:,:,T) = (eye(p) - K(:,T)*G(T,:))*F*P(:,:,T-1); % %A12

    for t = T:-1:3 % stop at 3 because use of t-2
       P_Tm2(:,:,t-1) = P_m1(:,:,t-1)*J(:,:,t-2)' + J(:,:,t-1)*(P_Tm2(:,:,t)-F*P(:,:,t-1))*J(:,:,t-2)'; % A11
    end
end
T = 500;
nbassets = 3;
G = .1 + randn(T,nbassets); % random walk trajectories
y = (1:T).';
y = 1.01.^y; % 1 * T % Exponential 1% returns curve