--- /dev/null
+function [ARF,RCF,PE,DC,varargout] = mvar(Y, Pmax, Mode);
+% MVAR estimates parameters of the Multi-Variate AutoRegressive model
+%
+% Y(t) = Y(t-1) * A1 + ... + Y(t-p) * Ap + X(t);
+% whereas
+% Y(t) is a row vecter with M elements Y(t) = y(t,1:M)
+%
+% Several estimation algorithms are implemented, all estimators
+% can handle data with missing values encoded as NaNs.
+%
+% [AR,RC,PE] = mvar(Y, p);
+% [AR,RC,PE] = mvar(Y, p, Mode);
+%
+% with
+% AR = [A1, ..., Ap];
+%
+% INPUT:
+% Y Multivariate data series
+% p Model order
+% Mode determines estimation algorithm
+%
+% OUTPUT:
+% AR multivariate autoregressive model parameter
+% RC reflection coefficients (= -PARCOR coefficients)
+% PE remaining error variances for increasing model order
+% PE(:,p*M+[1:M]) is the residual variance for model order p
+%
+% All input and output parameters are organized in columns, one column
+% corresponds to the parameters of one channel.
+%
+% Mode determines estimation algorithm.
+% 1: Correlation Function Estimation method using biased correlation function estimation method
+% also called the 'multichannel Yule-Walker' [1,2]
+% 6: Correlation Function Estimation method using unbiased correlation function estimation method
+%
+% 2: Partial Correlation Estimation: Vieira-Morf [2] using unbiased covariance estimates.
+% In [1] this mode was used and (incorrectly) denominated as Nutall-Strand.
+% Its the DEFAULT mode; according to [1] it provides the most accurate estimates.
+% 5: Partial Correlation Estimation: Vieira-Morf [2] using biased covariance estimates.
+% Yields similar results than Mode=2;
+%
+% 3: buggy: Partial Correlation Estimation: Nutall-Strand [2] (biased correlation function)
+% 9: Partial Correlation Estimation: Nutall-Strand [2] (biased correlation function)
+% 7: Partial Correlation Estimation: Nutall-Strand [2] (unbiased correlation function)
+% 8: Least Squares w/o nans in Y(t):Y(t-p)
+% 10: ARFIT [3]
+% 11: BURGV [4]
+% 13: modified BURGV -
+% 14: modified BURGV [4]
+% 15: Least Squares based on correlation matrix
+% 22: Modified Partial Correlation Estimation: Vieira-Morf [2,5] using unbiased covariance estimates.
+% 25: Modified Partial Correlation Estimation: Vieira-Morf [2,5] using biased covariance estimates.
+%
+% 90,91,96: Experimental versions
+%
+% Imputation methods:
+% 100+Mode:
+% 200+Mode: forward, past missing values are assumed zero
+% 300+Mode: backward, past missing values are assumed zero
+% 400+Mode: forward+backward, past missing values are assumed zero
+% 1200+Mode: forward, past missing values are replaced with predicted value
+% 1300+Mode: backward, 'past' missing values are replaced with predicted value
+% 1400+Mode: forward+backward, 'past' missing values are replaced with predicted value
+% 2200+Mode: forward, past missing values are replaced with predicted value + noise to prevent decaying
+% 2300+Mode: backward, past missing values are replaced with predicted value + noise to prevent decaying
+% 2400+Mode: forward+backward, past missing values are replaced with predicted value + noise to prevent decaying
+%
+%
+%
+
+% REFERENCES:
+% [1] A. Schloegl, Comparison of Multivariate Autoregressive Estimators.
+% Signal processing, Elsevier B.V. (in press).
+% available at http://dx.doi.org/doi:10.1016/j.sigpro.2005.11.007
+% [2] S.L. Marple 'Digital Spectral Analysis with Applications' Prentice Hall, 1987.
+% [3] Schneider and Neumaier)
+% [4] Stijn de Waele, 2003
+% [5] M. Morf, et al. Recursive Multichannel Maximum Entropy Spectral Estimation,
+% IEEE trans. GeoSci. Elec., 1978, Vol.GE-16, No.2, pp85-94.
+%
+%
+% A multivariate inverse filter can be realized with
+% [AR,RC,PE] = mvar(Y,P);
+% e = mvfilter([eye(size(AR,1)),-AR],eye(size(AR,1)),Y);
+%
+% see also: MVFILTER, MVFREQZ, COVM, SUMSKIPNAN, ARFIT2
+
+% $Id: mvar.m 9609 2012-02-10 10:18:00Z schloegl $
+% Copyright (C) 1996-2006,2011,2012 by Alois Schloegl <alois.schloegl@ist.ac.at>
+% This is part of the TSA-toolbox. See also
+% http://pub.ist.ac.at/~schloegl/matlab/tsa/
+% http://octave.sourceforge.net/
+% http://biosig.sourceforge.net/
+%
+% This program is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+% Inititialization
+[N,M] = size(Y);
+
+if nargin<2,
+ Pmax=max([N,M])-1;
+end;
+
+if iscell(Y)
+ Pmax = min(max(N ,M ),Pmax);
+ C = Y;
+end;
+if nargin<3,
+ % according to [1], and other internal validations this is in many cases the best algorithm
+ Mode=2;
+end;
+
+[C(:,1:M),n] = covm(Y,'M');
+PE(:,1:M) = C(:,1:M)./n;
+if 0,
+elseif Mode==0; % this method is broken
+ fprintf('Warning MVAR: Mode=0 is broken.\n')
+ C(:,1:M) = C(:,1:M)/N;
+ F = Y;
+ B = Y;
+ PEF = C(:,1:M); %?% PEF = PE(:,1:M);
+ PEB = C(:,1:M);
+ for K=1:Pmax,
+ [D,n] = covm(Y(K+1:N,:),Y(1:N-K,:),'M');
+ D = D/N;
+ ARF(:,K*M+(1-M:0)) = D/PEB;
+ ARB(:,K*M+(1-M:0)) = D'/PEF;
+
+ tmp = F(K+1:N,:) - B(1:N-K,:)*ARF(:,K*M+(1-M:0))';
+ B(1:N-K,:) = B(1:N-K,:) - F(K+1:N,:)*ARB(:,K*M+(1-M:0))';
+ F(K+1:N,:) = tmp;
+
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ PEF = [eye(M) - ARF(:,K*M+(1-M:0))*ARB(:,K*M+(1-M:0))]*PEF;
+ PEB = [eye(M) - ARB(:,K*M+(1-M:0))*ARF(:,K*M+(1-M:0))]*PEB;
+ PE(:,K*M+(1:M)) = PEF;
+ end;
+
+
+elseif Mode==1, %%%%% Levinson-Wiggens-Robinson (LWR) algorithm using biased correlation function
+ % ===== In [1,2] this algorithm is denoted 'Multichannel Yule-Walker' ===== %
+ C(:,1:M) = C(:,1:M)/N;
+ PEF = C(:,1:M);
+ PEB = C(:,1:M);
+
+ for K=1:Pmax,
+ [C(:,K*M+(1:M)),n] = covm(Y(K+1:N,:),Y(1:N-K,:),'M');
+ C(:,K*M+(1:M)) = C(:,K*M+(1:M))/N;
+
+ D = C(:,K*M+(1:M));
+ for L = 1:K-1,
+ D = D - ARF(:,L*M+(1-M:0))*C(:,(K-L)*M+(1:M));
+ end;
+ ARF(:,K*M+(1-M:0)) = D / PEB;
+ ARB(:,K*M+(1-M:0)) = D'/ PEF;
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ PEF = [eye(M) - ARF(:,K*M+(1-M:0))*ARB(:,K*M+(1-M:0))]*PEF;
+ PEB = [eye(M) - ARB(:,K*M+(1-M:0))*ARF(:,K*M+(1-M:0))]*PEB;
+ PE(:,K*M+(1:M)) = PEF;
+ end;
+
+
+elseif Mode==6, %%%%% Levinson-Wiggens-Robinson (LWR) algorithm using unbiased correlation function
+ C(:,1:M) = C(:,1:M)/N;
+ PEF = C(:,1:M); %?% PEF = PE(:,1:M);
+ PEB = C(:,1:M);
+
+ for K = 1:Pmax,
+ [C(:,K*M+(1:M)),n] = covm(Y(K+1:N,:),Y(1:N-K,:),'M');
+ C(:,K*M+(1:M)) = C(:,K*M+(1:M))./n;
+ %C{K+1} = C{K+1}/N;
+
+ D = C(:,K*M+(1:M));
+ for L = 1:K-1,
+ D = D - ARF(:,L*M+(1-M:0))*C(:,(K-L)*M+(1:M));
+ end;
+ ARF(:,K*M+(1-M:0)) = D / PEB;
+ ARB(:,K*M+(1-M:0)) = D'/ PEF;
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ PEF = [eye(M) - ARF(:,K*M+(1-M:0))*ARB(:,K*M+(1-M:0))]*PEF;
+ PEB = [eye(M) - ARB(:,K*M+(1-M:0))*ARF(:,K*M+(1-M:0))]*PEB;
+ PE(:,K*M+(1:M)) = PEF;
+ end;
+
+
+elseif Mode==2 %%%%% Partial Correlation Estimation: Vieira-Morf Method [2] with unbiased covariance estimation
+ %===== In [1] this algorithm is denoted 'Nutall-Strand with unbiased covariance' =====%
+ %C(:,1:M) = C(:,1:M)/N;
+ F = Y;
+ B = Y;
+ %PEF = C(:,1:M);
+ %PEB = C(:,1:M);
+ PEF = PE(:,1:M);
+ PEB = PE(:,1:M);
+ for K = 1:Pmax,
+ [D,n] = covm(F(K+1:N,:),B(1:N-K,:),'M');
+ D = D./n;
+
+ ARF(:,K*M+(1-M:0)) = D / PEB;
+ ARB(:,K*M+(1-M:0)) = D'/ PEF;
+
+ tmp = F(K+1:N,:) - B(1:N-K,:)*ARF(:,K*M+(1-M:0)).';
+ B(1:N-K,:) = B(1:N-K,:) - F(K+1:N,:)*ARB(:,K*M+(1-M:0)).';
+ F(K+1:N,:) = tmp;
+
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ [PEF,n] = covm(F(K+1:N,:),F(K+1:N,:),'M');
+ PEF = PEF./n;
+
+ [PEB,n] = covm(B(1:N-K,:),B(1:N-K,:),'M');
+ PEB = PEB./n;
+
+ PE(:,K*M+(1:M)) = PEF;
+ end;
+
+
+elseif Mode==5 %%%%% Partial Correlation Estimation: Vieira-Morf Method [2] with biased covariance estimation
+ %===== In [1] this algorithm is denoted 'Nutall-Strand with biased covariance' ===== %
+
+ F = Y;
+ B = Y;
+ PEF = C(:,1:M);
+ PEB = C(:,1:M);
+ for K=1:Pmax,
+ [D,n] = covm(F(K+1:N,:),B(1:N-K,:),'M');
+ %D=D/N;
+
+ ARF(:,K*M+(1-M:0)) = D / PEB;
+ ARB(:,K*M+(1-M:0)) = D'/ PEF;
+
+ tmp = F(K+1:N,:) - B(1:N-K,:)*ARF(:,K*M+(1-M:0)).';
+ B(1:N-K,:) = B(1:N-K,:) - F(K+1:N,:)*ARB(:,K*M+(1-M:0)).';
+ F(K+1:N,:) = tmp;
+
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ [PEB,n] = covm(B(1:N-K,:),B(1:N-K,:),'M');
+ %PEB = D/N;
+
+ [PEF,n] = covm(F(K+1:N,:),F(K+1:N,:),'M');
+ %PEF = D/N;
+
+ %PE(:,K*M+(1:M)) = PEF;
+ PE(:,K*M+(1:M)) = PEF./n;
+ end;
+
+
+elseif 0, Mode==3 %%%%% Partial Correlation Estimation: Nutall-Strand Method [2] with biased covariance estimation
+ %%% OBSOLETE because its buggy, use Mode=9 instead.
+ % C(:,1:M) = C(:,1:M)/N;
+ F = Y;
+ B = Y;
+ PEF = C(:,1:M);
+ PEB = C(:,1:M);
+ for K=1:Pmax,
+ [D, n] = covm(F(K+1:N,:),B(1:N-K,:),'M');
+ D = D./N;
+
+ ARF(:,K*M+(1-M:0)) = 2*D / (PEB+PEF);
+ ARB(:,K*M+(1-M:0)) = 2*D'/ (PEF+PEB);
+
+ tmp = F(K+1:N,:) - B(1:N-K,:)*ARF(:,K*M+(1-M:0)).';
+ B(1:N-K,:) = B(1:N-K,:) - F(K+1:N,:)*ARB(:,K*M+(1-M:0)).';
+ F(K+1:N,:) = tmp;
+
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ %RCF{K} = ARF{K};
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+
+ [PEF,n] = covm(F(K+1:N,:),F(K+1:N,:),'M');
+ PEF = PEF./N;
+
+ [PEB,n] = covm(B(1:N-K,:),B(1:N-K,:),'M');
+ PEB = PEB./N;
+
+ %PE(:,K*M+(1:M)) = PEF;
+ PE(:,K*M+(1:M)) = PEF./n;
+ end;
+
+
+elseif Mode==7 %%%%% Partial Correlation Estimation: Nutall-Strand Method [2] with unbiased covariance estimation
+
+ F = Y;
+ B = Y;
+ PEF = PE(:,1:M);
+ PEB = PE(:,1:M);
+ for K = 1:Pmax,
+ [D] = covm(F(K+1:N,:),B(1:N-K,:),'M');
+ %D = D./n;
+
+ ARF(:,K*M+(1-M:0)) = 2*D / (PEB+PEF);
+ ARB(:,K*M+(1-M:0)) = 2*D'/ (PEF+PEB);
+
+ tmp = F(K+1:N,:) - B(1:N-K,:)*ARF(:,K*M+(1-M:0)).';
+ B(1:N-K,:) = B(1:N-K,:) - F(K+1:N,:)*ARB(:,K*M+(1-M:0)).';
+ F(K+1:N,:) = tmp;
+
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ %RCF{K} = ARF{K};
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+
+ [PEF] = covm(F(K+1:N,:),F(K+1:N,:),'M');
+ %PEF = PEF./n;
+
+ [PEB] = covm(B(1:N-K,:),B(1:N-K,:),'M');
+ %PEB = PEB./n;
+
+ %PE{K+1} = PEF;
+ PE(:,K*M+(1:M)) = PEF;
+ end;
+
+
+elseif any(Mode==[3,9]) %%%%% Partial Correlation Estimation: Nutall-Strand Method [2] with biased covariance estimation
+ %% same as 3 but with fixed normalization
+ F = Y;
+ B = Y;
+ PEF = C(:,1:M);
+ PEB = C(:,1:M);
+ for K=1:Pmax,
+ [D, n] = covm(F(K+1:N,:),B(1:N-K,:),'M');
+
+ ARF(:,K*M+(1-M:0)) = 2*D / (PEB+PEF);
+ ARB(:,K*M+(1-M:0)) = 2*D'/ (PEF+PEB);
+
+ tmp = F(K+1:N,:) - B(1:N-K,:)*ARF(:,K*M+(1-M:0)).';
+ B(1:N-K,:) = B(1:N-K,:) - F(K+1:N,:)*ARB(:,K*M+(1-M:0)).';
+ F(K+1:N,:) = tmp;
+
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ %RCF{K} = ARF{K};
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+
+ [PEF,nf] = covm(F(K+1:N,:),F(K+1:N,:),'M');
+ [PEB,nb] = covm(B(1:N-K,:),B(1:N-K,:),'M');
+
+ %PE(:,K*M+(1:M)) = PEF;
+ PE(:,K*M+(1:M)) = PEF./nf;
+ end;
+
+
+elseif Mode==4, %%%%% Kay, not fixed yet.
+ fprintf('Warning MVAR: Mode=4 is broken.\n')
+
+ C(:,1:M) = C(:,1:M)/N;
+ K = 1;
+ [C(:,M+(1:M)),n] = covm(Y(2:N,:),Y(1:N-1,:));
+ C(:,M+(1:M)) = C(:,M+(1:M))/N; % biased estimate
+
+ D = C(:,M+(1:M));
+ ARF(:,1:M) = C(:,1:M)\D;
+ ARB(:,1:M) = C(:,1:M)\D';
+ RCF(:,1:M) = ARF(:,1:M);
+ RCB(:,1:M) = ARB(:,1:M);
+ PEF = C(:,1:M)*[eye(M) - ARB(:,1:M)*ARF(:,1:M)];
+ PEB = C(:,1:M)*[eye(M) - ARF(:,1:M)*ARB(:,1:M)];
+
+ for K=2:Pmax,
+ [C(:,K*M+(1:M)),n] = covm(Y(K+1:N,:),Y(1:N-K,:),'M');
+ C(:,K*M+(1:M)) = C(:,K*M+(1:M)) / N; % biased estimate
+
+ D = C(:,K*M+(1:M));
+ for L = 1:K-1,
+ D = D - C(:,(K-L)*M+(1:M))*ARF(:,L*M+(1-M:0));
+ end;
+
+ ARF(:,K*M+(1-M:0)) = PEB \ D;
+ ARB(:,K*M+(1-M:0)) = PEF \ D';
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0)) ;
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0)) ;
+
+ PEF = PEF*[eye(M) - ARB(:,K*M+(1-M:0)) *ARF(:,K*M+(1-M:0)) ];
+ PEB = PEB*[eye(M) - ARF(:,K*M+(1-M:0)) *ARB(:,K*M+(1-M:0)) ];
+ PE(:,K*M+(1:M)) = PEF;
+ end;
+
+
+elseif Mode==8, %%%%% Least Squares
+ ix = Pmax+1:N;
+ y = repmat(NaN,N-Pmax,M*Pmax);
+ for k = 1:Pmax,
+ y(:,k*M+[1-M:0]) = Y(ix-k,:);
+ end;
+ ix2 = ~any(isnan([Y(ix,:),y]),2);
+ ARF = Y(ix(ix2),:)'/y(ix2,:)';
+ PE = covm(Y(ix,:) - y*ARF');
+ RCF = zeros(M,M*Pmax);
+
+
+elseif Mode==10, %%%%% ARFIT
+ try
+ RCF = [];
+ [w, ARF, PE] = arfit(Y, Pmax, Pmax, 'sbc', 'zero');
+ catch
+ ARF = zeros(M,M*Pmax);
+ RCF = ARF;
+ end;
+
+
+elseif Mode==11, %%%%% de Waele 2003
+ %%% OBSOLETE
+ warning('MVAR: mode=11 is obsolete use Mode 13 or 14!');
+ [pc,R0] = burgv(reshape(Y',[M,1,N]),Pmax);
+ try,
+ [ARF,ARB,Pf,Pb,RCF,RCB] = pc2parv(pc,R0);
+ catch
+ [RCF,RCB,Pf,Pb] = pc2rcv(pc,R0);
+ [ARF,ARB,Pf,Pb] = pc2parv(pc,R0);
+ end;
+ ARF = -reshape(ARF(:,:,2:end),[M,M*Pmax]);
+ RCF = -reshape(RCF(:,:,2:end),[M,M*Pmax]);
+ PE = reshape(Pf,[M,M*(Pmax+1)]);
+
+
+elseif Mode==12,
+ %%% OBSOLETE
+ warning('MVAR: mode=12 is obsolete use Mode 13 or 14!');
+ % this is equivalent to Mode==11
+ [pc,R0] = burgv(reshape(Y',[M,1,N]),Pmax);
+ [rcf,rcb,Pf,Pb] = pc2rcv(pc,R0);
+
+ %%%%% Convert reflection coefficients RC to autoregressive parameters
+ ARF = zeros(M,M*Pmax);
+ ARB = zeros(M,M*Pmax);
+ for K = 1:Pmax,
+ ARF(:,K*M+(1-M:0)) = -rcf(:,:,K+1);
+ ARB(:,K*M+(1-M:0)) = -rcb(:,:,K+1);
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+ end;
+ RCF = -reshape(rcf(:,:,2:end),[M,M*Pmax]);
+ PE = reshape(Pf,[M,M*(Pmax+1)]);
+
+
+elseif Mode==13,
+ % this is equivalent to Mode==11 but can deal with missing values
+ %%%%%%%%%%% [pc,R0] = burgv_nan(reshape(Y',[M,1,N]),Pmax,1);
+ % Copyright S. de Waele, March 2003 - modified Alois Schloegl, 2009
+ I = eye(M);
+
+ sz = [M,M,Pmax+1];
+ pc= zeros(sz); pc(:,:,1) =I;
+ K = zeros(sz); K(:,:,1) =I;
+ Kb= zeros(sz); Kb(:,:,1) =I;
+ P = zeros(sz);
+ Pb= zeros(sz);
+
+ %[P(:,:,1)]= covm(Y);
+ [P(:,:,1)]= PE(:,1:M); % normalized
+ Pb(:,:,1)= P(:,:,1);
+ f = Y;
+ b = Y;
+
+ %the recursive algorithm
+ for i = 1:Pmax,
+ v = f(2:end,:);
+ w = b(1:end-1,:);
+
+ %% normalized, unbiased
+ Rvv = covm(v); %Pfhat
+ Rww = covm(w); %Pbhat
+ Rvw = covm(v,w); %Pfbhat
+ Rwv = covm(w,v); % = Rvw', written out for symmetry
+ delta = lyap(Rvv*inv(P(:,:,i)),inv(Pb(:,:,i))*Rww,-2*Rvw);
+
+ TsqrtS = chol( P(:,:,i))'; %square root M defined by: M=Tsqrt(M)*Tsqrt(M)'
+ TsqrtSb= chol(Pb(:,:,i))';
+ pc(:,:,i+1) = inv(TsqrtS)*delta*inv(TsqrtSb)';
+
+ %The forward and backward reflection coefficient
+ K(:,:,i+1) = -TsqrtS *pc(:,:,i+1) *inv(TsqrtSb);
+ Kb(:,:,i+1)= -TsqrtSb*pc(:,:,i+1)'*inv(TsqrtS);
+
+ %filtering the reflection coefficient out:
+ f = (v'+ K(:,:,i+1)*w')';
+ b = (w'+Kb(:,:,i+1)*v')';
+
+ %The new R and Rb:
+ %residual matrices
+ P(:,:,i+1) = (I-TsqrtS *pc(:,:,i+1) *pc(:,:,i+1)'*inv(TsqrtS ))*P(:,:,i);
+ Pb(:,:,i+1) = (I-TsqrtSb*pc(:,:,i+1)'*pc(:,:,i+1) *inv(TsqrtSb))*Pb(:,:,i);
+ end %for i = 1:Pmax,
+ R0 = PE(:,1:M);
+
+ %% [rcf,rcb,Pf,Pb] = pc2rcv(pc,R0);
+ rcf = zeros(sz); rcf(:,:,1) = I;
+ Pf = zeros(sz); Pf(:,:,1) = R0;
+ rcb = zeros(sz); rcb(:,:,1) = I;
+ Pb = zeros(sz); Pb(:,:,1) = R0;
+
+ for p = 1:Pmax,
+ TsqrtPf = chol( Pf(:,:,p))'; %square root M defined by: M=Tsqrt(M)*Tsqrt(M)'
+ TsqrtPb= chol(Pb(:,:,p))';
+ %reflection coefficients
+ rcf(:,:,p+1) = -TsqrtPf *pc(:,:,p+1) *inv(TsqrtPb);
+ rcb(:,:,p+1)= -TsqrtPb*pc(:,:,p+1)'*inv(TsqrtPf );
+ %residual matrices
+ Pf(:,:,p+1) = (I-TsqrtPf *pc(:,:,p+1) *pc(:,:,p+1)'*inv(TsqrtPf ))*Pf(:,:,p);
+ Pb(:,:,p+1) = (I-TsqrtPb*pc(:,:,p+1)'*pc(:,:,p+1) *inv(TsqrtPb))*Pb(:,:,p);
+ end %for p = 2:order,
+ %%%%%%%%%%%%%% end %%%%%%
+
+
+ %%%%% Convert reflection coefficients RC to autoregressive parameters
+ ARF = zeros(M,M*Pmax);
+ ARB = zeros(M,M*Pmax);
+ for K = 1:Pmax,
+ ARF(:,K*M+(1-M:0)) = -rcf(:,:,K+1);
+ ARB(:,K*M+(1-M:0)) = -rcb(:,:,K+1);
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+ end;
+ RCF = -reshape(rcf(:,:,2:end),[M,M*Pmax]);
+ PE = reshape(Pf,[M,M*(Pmax+1)]);
+
+
+elseif Mode==14,
+ % this is equivalent to Mode==11 but can deal with missing values
+ %%%%%%%%%%%%%% [pc,R0] = burgv_nan(reshape(Y',[M,1,N]),Pmax,2);
+ % Copyright S. de Waele, March 2003 - modified Alois Schloegl, 2009
+ I = eye(M);
+
+ sz = [M,M,Pmax+1];
+ pc= zeros(sz); pc(:,:,1) =I;
+ K = zeros(sz); K(:,:,1) =I;
+ Kb= zeros(sz); Kb(:,:,1) =I;
+ P = zeros(sz);
+ Pb= zeros(sz);
+
+ %[P(:,:,1),nn]= covm(Y);
+ [P(:,:,1)]= C(:,1:M); %% no normalization
+ Pb(:,:,1)= P(:,:,1);
+ f = Y;
+ b = Y;
+
+ %the recursive algorithm
+ for i = 1:Pmax,
+ v = f(2:end,:);
+ w = b(1:end-1,:);
+
+ %% no normalization
+ [Rvv,nn] = covm(v); %Pfhat
+ [Rww,nn] = covm(w); %Pbhat
+ [Rvw,nn] = covm(v,w); %Pfbhat
+ [Rwv,nn] = covm(w,v); % = Rvw', written out for symmetry
+ delta = lyap(Rvv*inv(P(:,:,i)),inv(Pb(:,:,i))*Rww,-2*Rvw);
+
+ TsqrtS = chol( P(:,:,i))'; %square root M defined by: M=Tsqrt(M)*Tsqrt(M)'
+ TsqrtSb= chol(Pb(:,:,i))';
+ pc(:,:,i+1) = inv(TsqrtS)*delta*inv(TsqrtSb)';
+
+ %The forward and backward reflection coefficient
+ K(:,:,i+1) = -TsqrtS *pc(:,:,i+1) *inv(TsqrtSb);
+ Kb(:,:,i+1)= -TsqrtSb*pc(:,:,i+1)'*inv(TsqrtS);
+
+ %filtering the reflection coefficient out:
+ f = (v'+ K(:,:,i+1)*w')';
+ b = (w'+Kb(:,:,i+1)*v')';
+
+ %The new R and Rb:
+ %residual matrices
+ P(:,:,i+1) = (I-TsqrtS *pc(:,:,i+1) *pc(:,:,i+1)'*inv(TsqrtS ))*P(:,:,i);
+ Pb(:,:,i+1) = (I-TsqrtSb*pc(:,:,i+1)'*pc(:,:,i+1) *inv(TsqrtSb))*Pb(:,:,i);
+ end %for i = 1:Pmax,
+ R0 = PE(:,1:M);
+
+ %%%%%%%%%% [rcf,rcb,Pf,Pb] = pc2rcv(pc,R0);
+ sz = [M,M,Pmax+1];
+ rcf = zeros(sz); rcf(:,:,1) = I;
+ Pf = zeros(sz); Pf(:,:,1) = R0;
+ rcb = zeros(sz); rcb(:,:,1) = I;
+ Pb = zeros(sz); Pb(:,:,1) = R0;
+ for p = 1:Pmax,
+ TsqrtPf = chol( Pf(:,:,p))'; %square root M defined by: M=Tsqrt(M)*Tsqrt(M)'
+ TsqrtPb = chol(Pb(:,:,p))';
+ %reflection coefficients
+ rcf(:,:,p+1)= -TsqrtPf *pc(:,:,p+1) *inv(TsqrtPb);
+ rcb(:,:,p+1)= -TsqrtPb *pc(:,:,p+1)'*inv(TsqrtPf );
+ %residual matrices
+ Pf(:,:,p+1) = (I-TsqrtPf *pc(:,:,p+1) *pc(:,:,p+1)'*inv(TsqrtPf))*Pf(:,:,p);
+ Pb(:,:,p+1) = (I-TsqrtPb *pc(:,:,p+1)'*pc(:,:,p+1) *inv(TsqrtPb))*Pb(:,:,p);
+ end %for p = 2:order,
+ %%%%%%%%%%%%%% end %%%%%%
+
+ %%%%% Convert reflection coefficients RC to autoregressive parameters
+ ARF = zeros(M,M*Pmax);
+ ARB = zeros(M,M*Pmax);
+ for K = 1:Pmax,
+ ARF(:,K*M+(1-M:0)) = -rcf(:,:,K+1);
+ ARB(:,K*M+(1-M:0)) = -rcb(:,:,K+1);
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+ end;
+ RCF = -reshape(rcf(:,:,2:end),[M,M*Pmax]);
+ PE = reshape(Pf,[M,M*(Pmax+1)]);
+
+
+elseif Mode==15, %%%%% Least Squares
+ %% FIXME
+ for K=1:Pmax,
+ [C(:,K*M+(1:M)),n] = covm(Y(K+1:N,:),Y(1:N-K,:),'M');
+% C(K*M+(1:M),:) = C(K*M+(1:M),:)/N;
+ end;
+ ARF = C(:,1:M)'/C(:,M+1:end)';
+ PE = covm(C(:,1:M)' - ARF * C(:,M+1:end)');
+ RCF = zeros(M, M*Pmax);
+
+
+elseif 0,
+ %%%%% ARFIT and handling missing values
+ % compute QR factorization for model of order pmax
+ [R, scale] = arqr(Y, Pmax, 0);
+ % select order of model
+ popt = Pmax; % estimated optimum order
+ np = M*Pmax; % number of parameter vectors of length m
+ % decompose R for the optimal model order popt according to
+ %
+ % | R11 R12 |
+ % R=| |
+ % | 0 R22 |
+ %
+ R11 = R(1:np, 1:np);
+ R12 = R(1:np, Pmax+1:Pmax+M);
+ R22 = R(M*Pmax+1:Pmax+M, Pmax+1:Pmax+M);
+ A = (R11\R12)';
+ % return covariance matrix
+ dof = N-Pmax-M*Pmax; % number of block degrees of freedom
+ PE = R22'*R22./dof; % bias-corrected estimate of covariance matrix
+
+ try
+ RCF = [];
+ [w, ARF, PE] = arfit(Y, Pmax, Pmax, 'sbc', 'zero');
+ catch
+ ARF = zeros(M,M*Pmax);
+ RCF = ARF;
+ end;
+
+
+elseif Mode==22 %%%%% Modified Partial Correlation Estimation: Vieira-Morf [2,5] using unbiased covariance estimates.
+ %--------Initialization----------
+ F = Y;
+ B = Y;
+ [PEF, n] = covm(Y(2:N,:),'M');
+ PEF = PEF./n;
+ [PEB, n] = covm(Y(1:N-1,:),'M');
+ PEB = PEB./n;
+ %---------------------------------
+ for K = 1:Pmax,
+ %---Update the estimated error covariances(15.89) in [2]---
+ [PEFhat,n] = covm(F(K+1:N,:),'M');
+ PEFhat = PEFhat./n;
+
+ [PEBhat,n] = covm(B(1:N-K,:),'M');
+ PEBhat = PEBhat./n;
+
+ [PEFBhat,n] = covm(F(K+1:N,:),B(1:N-K,:),'M');
+ PEFBhat = PEFBhat./n;
+
+ %---Compute estimated normalized partial correlation matrix(15.88)in [2]---
+ Rho = inv(chol(PEFhat)')*PEFBhat*inv(chol(PEBhat));
+
+ %---Update forward and backward reflection coefficients (15.82) and (15.83) in [2]---
+ ARF(:,K*M+(1-M:0)) = chol(PEF)'*Rho*inv(chol(PEB)');
+ ARB(:,K*M+(1-M:0)) = chol(PEB)'*Rho'*inv(chol(PEF)');
+
+ %---------------------------------
+ tmp = F(K+1:N,:) - B(1:N-K,:)*ARF(:,K*M+(1-M:0)).';
+ B(1:N-K,:) = B(1:N-K,:) - F(K+1:N,:)*ARB(:,K*M+(1-M:0)).';
+ F(K+1:N,:) = tmp;
+
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ %---Update forward and backward error covariances (15.75) and (15.76) in [2]---
+ PEF = (eye(M)-ARF(:,K*M+(1-M:0))*ARB(:,K*M+(1-M:0)))*PEF;
+ PEB = (eye(M)-ARB(:,K*M+(1-M:0))*ARF(:,K*M+(1-M:0)))*PEB;
+
+ PE(:,K*M+(1:M)) = PEF;
+ end
+
+
+elseif Mode==25 %%%%Modified Partial Correlation Estimation: Vieira-Morf [2,5] using biased covariance estimates.
+ %--------Initialization----------
+ F = Y;
+ B = Y;
+ [PEF, n] = covm(Y(2:N,:),'M');
+ PEF = PEF./N;
+ [PEB, n] = covm(Y(1:N-1,:),'M');
+ PEB = PEB./N;
+ %---------------------------------
+ for K = 1:Pmax,
+ %---Update the estimated error covariances(15.89) in [2]---
+ [PEFhat,n] = covm(F(K+1:N,:),'M');
+ PEFhat = PEFhat./N;
+
+ [PEBhat,n] = covm(B(1:N-K,:),'M');
+ PEBhat = PEBhat./N;
+
+ [PEFBhat,n] = covm(F(K+1:N,:),B(1:N-K,:),'M');
+ PEFBhat = PEFBhat./N;
+
+ %---Compute estimated normalized partial correlation matrix(15.88)in [2]---
+ Rho = inv(chol(PEFhat)')*PEFBhat*inv(chol(PEBhat));
+
+ %---Update forward and backward reflection coefficients (15.82) and (15.83) in [2]---
+ ARF(:,K*M+(1-M:0)) = chol(PEF)'*Rho*inv(chol(PEB)');
+ ARB(:,K*M+(1-M:0)) = chol(PEB)'*Rho'*inv(chol(PEF)');
+
+ %---------------------------------
+ tmp = F(K+1:N,:) - B(1:N-K,:)*ARF(:,K*M+(1-M:0)).';
+ B(1:N-K,:) = B(1:N-K,:) - F(K+1:N,:)*ARB(:,K*M+(1-M:0)).';
+ F(K+1:N,:) = tmp;
+
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ %---Update forward and backward error covariances (15.75) and (15.76) in [2]---
+ PEF = (eye(M)-ARF(:,K*M+(1-M:0))*ARB(:,K*M+(1-M:0)))*PEF;
+ PEB = (eye(M)-ARB(:,K*M+(1-M:0))*ARF(:,K*M+(1-M:0)))*PEB;
+
+ PE(:,K*M+(1:M)) = PEF;
+ end
+
+
+
+
+%%%%% EXPERIMENTAL VERSIONS %%%%%
+
+elseif Mode==90;
+ % similar to MODE=0
+ %% not recommended
+ C(:,1:M) = C(:,1:M)/N;
+ F = Y;
+ B = Y;
+ PEF = PE(:,1:M); %CHANGED%
+ PEB = PE(:,1:M); %CHANGED%
+ for K=1:Pmax,
+ [D,n] = covm(Y(K+1:N,:),Y(1:N-K,:),'M');
+ D = D/N;
+ ARF(:,K*M+(1-M:0)) = D/PEB;
+ ARB(:,K*M+(1-M:0)) = D'/PEF;
+
+ tmp = F(K+1:N,:) - B(1:N-K,:)*ARF(:,K*M+(1-M:0))';
+ B(1:N-K,:) = B(1:N-K,:) - F(K+1:N,:)*ARB(:,K*M+(1-M:0))';
+ F(K+1:N,:) = tmp;
+
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ PEF = [eye(M) - ARF(:,K*M+(1-M:0))*ARB(:,K*M+(1-M:0))]*PEF;
+ PEB = [eye(M) - ARB(:,K*M+(1-M:0))*ARF(:,K*M+(1-M:0))]*PEB;
+ PE(:,K*M+(1:M)) = PEF;
+ end;
+
+
+elseif Mode==91, %%%%% Levinson-Wiggens-Robinson (LWR) algorithm using biased correlation function
+ % ===== In [1,2] this algorithm is denoted 'Multichannel Yule-Walker' ===== %
+ % similar to MODE=1
+ %% not recommended
+ C(:,1:M) = C(:,1:M)/N;
+ PEF = PE(:,1:M); %CHANGED%
+ PEB = PE(:,1:M); %CHANGED%
+
+ for K=1:Pmax,
+ [C(:,K*M+(1:M)),n] = covm(Y(K+1:N,:),Y(1:N-K,:),'M');
+ C(:,K*M+(1:M)) = C(:,K*M+(1:M))/N;
+
+ D = C(:,K*M+(1:M));
+ for L = 1:K-1,
+ D = D - ARF(:,L*M+(1-M:0))*C(:,(K-L)*M+(1:M));
+ end;
+ ARF(:,K*M+(1-M:0)) = D / PEB;
+ ARB(:,K*M+(1-M:0)) = D'/ PEF;
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ PEF = [eye(M) - ARF(:,K*M+(1-M:0))*ARB(:,K*M+(1-M:0))]*PEF;
+ PEB = [eye(M) - ARB(:,K*M+(1-M:0))*ARF(:,K*M+(1-M:0))]*PEB;
+ PE(:,K*M+(1:M)) = PEF;
+ end;
+
+
+elseif Mode==96, %%%%% Levinson-Wiggens-Robinson (LWR) algorithm using unbiased correlation function
+ % similar to MODE=6
+ %% not recommended
+ C(:,1:M) = C(:,1:M)/N;
+ PEF = PE(:,1:M); %CHANGED%
+ PEB = PE(:,1:M); %CHANGED%
+
+ for K = 1:Pmax,
+ [C(:,K*M+(1:M)),n] = covm(Y(K+1:N,:),Y(1:N-K,:),'M');
+ C(:,K*M+(1:M)) = C(:,K*M+(1:M))./n;
+
+ D = C(:,K*M+(1:M));
+ for L = 1:K-1,
+ D = D - ARF(:,L*M+(1-M:0))*C(:,(K-L)*M+(1:M));
+ end;
+ ARF(:,K*M+(1-M:0)) = D / PEB;
+ ARB(:,K*M+(1-M:0)) = D'/ PEF;
+ for L = 1:K-1,
+ tmp = ARF(:,L*M+(1-M:0)) - ARF(:,K*M+(1-M:0))*ARB(:,(K-L)*M+(1-M:0));
+ ARB(:,(K-L)*M+(1-M:0)) = ARB(:,(K-L)*M+(1-M:0)) - ARB(:,K*M+(1-M:0))*ARF(:,L*M+(1-M:0));
+ ARF(:,L*M+(1-M:0)) = tmp;
+ end;
+
+ RCF(:,K*M+(1-M:0)) = ARF(:,K*M+(1-M:0));
+ RCB(:,K*M+(1-M:0)) = ARB(:,K*M+(1-M:0));
+
+ PEF = [eye(M) - ARF(:,K*M+(1-M:0))*ARB(:,K*M+(1-M:0))]*PEF;
+ PEB = [eye(M) - ARB(:,K*M+(1-M:0))*ARF(:,K*M+(1-M:0))]*PEB;
+ PE(:,K*M+(1:M)) = PEF;
+ end;
+
+elseif Mode<100,
+ fprintf('Warning MVAR: Mode=%i not supported\n',Mode);
+
+%%%%% IMPUTATION METHODS %%%%%
+else
+
+ Mode0 = rem(Mode,100);
+ if ((Mode0 >= 10) && (Mode0 < 20)),
+ Mode0 = 1;
+ end;
+
+if 0,
+
+
+elseif Mode>=2400, % forward and backward
+% assuming that past missing values are already IMPUTED with the prediction value + innovation process
+% no decaying
+
+ [ARF,RCF,PE2] = mvar(Y, Pmax, Mode0);
+ c = chol( PE2 (:, M*Pmax+(1:M)));
+
+ Y1 = Y;
+ Y1(1,isnan(Y1(1,:))) = 0;
+ z = [];
+ for k = 2:size(Y,1)
+ [z1,z] = mvfilter(ARF,eye(M),Y1(k-1,:)',z);
+ ix = isnan(Y1(k,:));
+ z1 = z1 + (randn(1,M)*c)';
+ Y1(k,ix) = z1(ix);
+ end;
+
+ Y2 = flipud(Y);
+ [ARB,RCF,PE] = mvar(Y2, Pmax, Mode0);
+ Y2(1,isnan(Y2(1,:))) = 0;
+ z = [];
+ for k = 2:size(Y2,1)
+ [z2,z] = mvfilter(ARB,eye(M),Y2(k-1,:)',z);
+ ix = isnan(Y(size(Y,1)-k+1,:));
+ z2 = z2 + (randn(1,M)*c)';
+ Y2(k,ix) = (z2(ix)' + Y2(k,ix))/2;
+ end;
+ Y2 = flipud(Y2);
+
+ Z = (Y2+Y1)/2;
+ Y(isnan(Y)) = Z(isnan(Y));
+
+ [ARF,RCF,PE] = mvar(Y, Pmax, rem(Mode,100));
+
+
+elseif Mode>=2300, % backward prediction
+% assuming that past missing values are already IMPUTED with the prediction value + innovation process
+% no decaying
+
+ Y = flipud(Y);
+ [ARB,RCF,PE] = mvar(Y, Pmax, Mode0);
+ c = chol(PE(:,M*Pmax+(1:M)));
+ Y1 = Y;
+ Y1(1,isnan(Y1(1,:))) = 0;
+ z = [];
+ for k = 2:size(Y,1)
+ [z1,z] = mvfilter(ARB,eye(M),Y1(k-1,:)',z);
+ ix = isnan(Y1(k,:));
+ z1 = z1 + (randn(1,M)*c)';
+ Y1(k,ix) = z1(ix);
+ end;
+ Y1 = flipud(Y1);
+ [ARF,RCF,PE] = mvar(Y1, Pmax, rem(Mode,100));
+
+
+elseif Mode>=2200, % forward predictions,
+% assuming that past missing values are already IMPUTED with the prediction value + innovation process
+% no decaying
+ [ARF,RCF,PE] = mvar(Y, Pmax, Mode0);
+ c = chol(PE(:,M*Pmax+(1:M)));
+ Y1 = Y;
+ Y1(1,isnan(Y1(1,:))) = 0;
+ z = [];
+ for k = 2:size(Y,1)
+ [z1,z] = mvfilter(ARF,eye(M),Y1(k-1,:)',z);
+ ix = isnan(Y1(k,:));
+ z1 = z1 + (randn(1,M)*c)';
+ Y1(k,ix) = z1(ix);
+ end;
+ [ARF,RCF,PE] = mvar(Y1, Pmax, rem(Mode,100));
+
+
+elseif Mode>=1400, % forward and backward
+%assuming that past missing values are already IMPUTED with the prediction value
+ [ARF,RCF,PE] = mvar(Y, Pmax, Mode0);
+ Y1 = Y;
+ Y1(1,isnan(Y1(1,:))) = 0;
+ z = [];
+ for k = 2:size(Y,1)
+ [z1,z] = mvfilter(ARF,eye(M),Y1(k-1,:)',z);
+ ix = isnan(Y1(k,:));
+ Y1(k,ix) = z1(ix);
+ end;
+
+ Y2 = flipud(Y);
+ [ARB,RCF,PE] = mvar(Y2, Pmax, Mode0);
+ Y2(1,isnan(Y2(1,:))) = 0;
+ z = [];
+ for k = 2:size(Y2,1)
+ [z2,z] = mvfilter(ARB,eye(M),Y2(k-1,:)',z);
+ ix = isnan(Y2(k,:));
+ Y2(k,ix) = z2(ix)';
+ end;
+ Y2 = flipud(Y2);
+
+ Z = (Y2+Y1)/2;
+ Y(isnan(Y)) = Z(isnan(Y));
+
+ [ARF,RCF,PE] = mvar(Y, Pmax, rem(Mode,100));
+
+
+elseif Mode>=1300, % backward prediction
+ Y = flipud(Y);
+ [ARB,RCF,PE] = mvar(Y, Pmax, Mode0);
+ Y2 = Y;
+ Y2(1,isnan(Y2(1,:))) = 0;
+ z = [];
+ for k = 2:size(Y,1)
+ [z2,z] = mvfilter(ARB,eye(M),Y2(k-1,:)',z);
+ ix = isnan(Y2(k,:));
+ Y2(k,ix) = z2(ix);
+ end;
+ Y2 = flipud(Y2);
+ [ARF,RCF,PE] = mvar(Y2, Pmax, rem(Mode,100));
+
+
+elseif Mode>=1200, % forward predictions,
+%assuming that past missing values are already IMPUTED with the prediction value
+ [ARF,RCF,PE] = mvar(Y, Pmax, Mode0);
+ Y1 = Y;
+ Y1(1,isnan(Y1(1,:))) = 0;
+ z = [];
+ for k = 2:size(Y,1)
+ [z1,z] = mvfilter(ARF,eye(M),Y1(k-1,:)',z);
+ ix = isnan(Y1(k,:));
+ Y1(k,ix) = z1(ix);
+ end;
+ [ARF,RCF,PE] = mvar(Y1, Pmax, rem(Mode,100));
+
+
+elseif Mode>=400, % forward and backward
+% assuming that 'past' missing values are ZERO
+ [ARF,RCF,PE] = mvar(Y, Pmax, Mode0);
+ Y1 = Y;
+ Y1(isnan(Y)) = 0;
+ Z1 = mvfilter([zeros(M),ARF],eye(M),Y1')';
+ Y1(isnan(Y)) = Z1(isnan(Y));
+
+ Y = flipud(Y);
+ [ARB,RCF,PE] = mvar(Y, Pmax, Mode0);
+ Y2 = Y;
+ Y2(isnan(Y)) = 0;
+ Z2 = mvfilter([zeros(M),ARB],eye(M),Y2')';
+ Y2(isnan(Y)) = Z2(isnan(Y));
+ Y2 = flipud(Y2);
+
+ [ARF,RCF,PE] = mvar((Y1+Y2)/2, Pmax, rem(Mode,100));
+
+
+elseif Mode>=300, % backward prediction
+% assuming that 'past' missing values are ZERO
+ Y = flipud(Y);
+ [ARB,RCF,PE] = mvar(Y, Pmax, Mode0);
+ Y2 = Y;
+ Y2(isnan(Y)) = 0;
+ Z2 = mvfilter([zeros(M),ARB],eye(M),Y2')';
+ Y2(isnan(Y)) = Z2(isnan(Y));
+ Y2 = flipud(Y2);
+
+ [ARF,RCF,PE] = mvar(Y2, Pmax, rem(Mode,100));
+
+
+elseif Mode>=200,
+% forward predictions, assuming that past missing values are ZERO
+ [ARF,RCF,PE] = mvar(Y, Pmax, Mode0);
+ Y1 = Y;
+ Y1(isnan(Y)) = 0;
+ Z1 = mvfilter([zeros(M),ARF],eye(M),Y1')';
+ Y1(isnan(Y)) = Z1(isnan(Y));
+
+ [ARF,RCF,PE] = mvar(Y1, Pmax, rem(Mode,100));
+
+
+elseif Mode>=100,
+ [ARF,RCF,PE] = mvar(Y, Pmax, Mode0);
+ Z1 = mvfilter(ARF,eye(M),Y')';
+ Z1 = [zeros(1,M); Z1(1:end-1,:)];
+ Y(isnan(Y)) = Z1(isnan(Y));
+ [ARF,RCF,PE] = mvar(Y, Pmax, rem(Mode,100));
+
+
+end;
+end;
+
+
+if any(ARF(:)==inf),
+% Test for matrix division bug.
+% This bug was observed in LNX86-ML5.3, 6.1 and 6.5, but not in SGI-ML6.5, LNX86-ML6.5, Octave 2.1.35-40; Other platforms unknown.
+p = 3;
+FLAG_MATRIX_DIVISION_ERROR = ~all(all(isnan(repmat(0,p)/repmat(0,p)))) | ~all(all(isnan(repmat(nan,p)/repmat(nan,p))));
+
+if FLAG_MATRIX_DIVISION_ERROR,
+ %fprintf(2,'%%% Warning MVAR: Bug in Matrix-Division 0/0 and NaN/NaN yields INF instead of NAN. Workaround is applied.\n');
+ warning('MVAR: bug in Matrix-Division 0/0 and NaN/NaN yields INF instead of NAN. Workaround is applied.');
+
+ %%%%% Workaround
+ ARF(ARF==inf)=NaN;
+ RCF(RCF==inf)=NaN;
+end;
+end;
+
+%MAR = zeros(M,M*Pmax);
+DC = zeros(M);
+for K = 1:Pmax,
+% VAR{K+1} = -ARF(:,K*M+(1-M:0))';
+ DC = DC + ARF(:,K*M+(1-M:0))'.^2; %DC meausure [3]
+end;
+