MATLAB: Not Enough Input Arguements - matlab

I've attempted to run this code multiple times and have had zero luck since I added in the last for loop. Before the error, the vector k wouldn't update so the vector L was the same number repeated.
I can't figure out why I am getting the 'Not enough input arguments' error when it was working fine beforehand.
Any help would be much appreciated!
% Set up parameters of the functions
omega = 2*pi/10; % 1/s
g = 9.81; % m/s^2
h = 20; % m
parms = [omega, g, h];
% Set up the root finding variables
etol = 1e-6; % convergence criteria
iter = 100; % maximum number of iterations
f = #my_fun; % function pointer to my_func
fp = #my_fprime; % function pointer to my_fprime
k0 = kguess(parms); % initial guess for root
% Find the root
[k, error, n_iterations] = newtraph(f, fp, k0, etol, iter, parms);
% Get the wavelength
if n_iterations < iter
% Converged correctly
L = 2 * pi / k;
else
% Did not converge
disp('ERROR: Maximum number of iterations exceeded')
return
end
wave = load('wavedata.dat');
dt = 0.04; %s
%dh = 0.234; %water depth in meters
wave = wave*.01; %covnverts from meters to cm
nw = wave([926:25501],1);
a = length(nw);
t = 0;
spot = 1;
points = zeros(1,100);
for i = 1:a-1
t=t+dt;
if nw(i) < 0
if nw(i+1) > 0
points(spot)=t;
spot=spot+1;
t=0;
end
end
end
omega = 2*pi./points; %w
l = length(points);
L = zeros(1,509);
k = zeros(1,509);
for j = 1:l
g = 9.81; % m/s^2
h = 0.234; % m
parms = [omega(j), g, h];
% Set up the root finding variables
etol = 1e-6; % convergence criteria
iter = 100; % maximum number of iterations
f = #my_fun; % function pointer to my_func
fp = #my_fprime; % function pointer to my_fprime
k0(j) = kguess(parms); % initial guess for root
% Find the root
[k(j), error, n_iterations] = newtraph(f, fp, k0(j), etol, iter, parms);
% Get the wavelength
if n_iterations < iter
% Converged correctly
L(j) = 2 * pi / k(j);
else
% Did not converge
disp('ERROR: Maximum number of iterations exceeded')
return
end
end
function [ f ] = my_fun(k,parms)
%MY_FUN creates a function handle for linear dispersion
% Detailed explanation goes here
w = parms(1) ;
g = parms(2);
h = parms(3);
f = g*k*tanh(k*h)-(w^2);
end
function [ fp ] = my_fprime(k,parms)
%MY_FPRIME creates a function handle for first derivative of linear
% dispersion.
g = parms(2);
h = parms(3);
% w = 2*pi/10; % 1/s
% g = 9.81; % m/s^2
% h = 20; % m
fp = g*(k*h*((sech(k*h)).^2) + tanh(k*h));
end
function [ k, error, n_iterations ] = newtraph( f, fp, k0, etol, iterA, parms )
%NEWTRAPH Estimates the value of k using the newton raphson method.
if nargin<3,error('at least 3 input arguments required'),end
if nargin<4|isempty(etol),es=etol;end
if nargin<5|isempty(iterA),maxit=iterA;end
iter = 0;
k = k0;
%func =#f;
%dfunc =#fp;
while (1)
xrold = k;
k = k - f(k)/fp(k);
iter = iter + 1;
if k ~= 0, ea = abs((k - xrold)/k) * 100; end
if ea <= etol | iter >= iterA, break, end
end
error = ea;
n_iterations = iter;
end

In function newtraph at line 106 (second line in the while(1) loop), you forgot to pass parms to the function call f:
k = k - f(k)/fp(k);
should become
k = k - f(k,parms)/fp(k,parms);

Related

Steepest Descent using Armijo rule

I want to determine the Steepest descent of the Rosenbruck function using Armijo steplength where x = [-1.2, 1]' (the initial column vector).
The problem is, that the code has been running for a long time. I think there will be an infinite loop created here. But I could not understand where the problem was.
Could anyone help me?
n=input('enter the number of variables n ');
% Armijo stepsize rule parameters
x = [-1.2 1]';
s = 10;
m = 0;
sigma = .1;
beta = .5;
obj=func(x);
g=grad(x);
k_max = 10^5;
k=0; % k = # iterations
nf=1; % nf = # function eval.
x_new = zeros([],1) ; % empty vector which can be filled if length is not known ;
[X,Y]=meshgrid(-2:0.5:2);
fx = 100*(X.^2 - Y).^2 + (X-1).^2;
contour(X, Y, fx, 20)
while (norm(g)>10^(-3)) && (k<k_max)
d = -g./abs(g); % steepest descent direction
s = 1;
newobj = func(x + beta.^m*s*d);
m = m+1;
if obj > newobj - (sigma*beta.^m*s*g'*d)
t = beta^m *s;
x = x + t*d;
m_new = m;
newobj = func(x + t*d);
nf = nf+1;
else
m = m+1;
end
obj=newobj;
g=grad(x);
k = k + 1;
x_new = [x_new, x];
end
% Output x and k
x_new, k, nf
fprintf('Optimal Solution x = [%f, %f]\n', x(1), x(2))
plot(x_new)
function y = func(x)
y = 100*(x(1)^2 - x(2))^2 + (x(1)-1)^2;
end
function y = grad(x)
y(1) = 100*(2*(x(1)^2-x(2))*2*x(1)) + 2*(x(1)-1);
end

how run kmean algorithm on sift keypoint in matlab

I need to run the K-Means algorithm on the key points of the Sift algorithm in MATLAB .I want to cluster the key points in the image but I do not know how to do it.
First, put the key points into X with x coordinates in the first column and y coordinates in the second column like this
X=[reshape(keypxcoord,numel(keypxcoord),1),reshape(keypycoord,numel(keypycoord),1))]
Then if you have the statistical toolbox, you can just use the built in 'kmeans' function lik this
output = kmeans(X,num_clusters)
Otherwise, write your own kmeans function:
function [ min_group, mu ] = mykmeans( X,K )
%MYKMEANS
% X = N obervations of D element vectors
% K = number of centroids
assert(K > 0);
D = size(X,1); %No. of r.v.
N = size(X,2); %No. of observations
group_size = zeros(1,K);
min_group = zeros(1,N);
step = 0;
%% init centroids
mu = kpp(X,K);
%% 2-phase iterative approach (local then global)
while step < 400
%% phase 1, batch update
old_group = min_group;
% computing distances
d2 = distances2(X,mu);
% reassignment all points to closest centroids
[~, min_group] = min(d2,[],1);
% recomputing centroids (K number of means)
for k = 1 : K
group_size(k) = sum(min_group==k);
% check empty group
%if group_size(k) == 0
assert(group_size(k)>0);
%else
mu(:,k) = sum(X(:,min_group==k),2)/group_size(k);
%end
end
changed = sum(min_group ~= old_group);
p1_converged = changed <= N*0.001;
%% phase 2, individual update
changed = 0;
for n = 1 : N
d2 = distances2(X(:,n),mu);
[~, new_group] = min(d2,[],1);
% recomputing centroids of affected groups
k = min_group(n);
if (new_group ~= k)
mu(:,k)=(mu(:,k)*group_size(k)-X(:,n));
group_size(k) = group_size(k) - 1;
mu(:,k)=mu(:,k)/group_size(k);
mu(:,new_group) = mu(:,new_group)*group_size(new_group)+ X(:,n);
group_size(new_group) = group_size(new_group) + 1;
mu(:,new_group)=mu(:,new_group)/group_size(new_group);
min_group(n) = new_group;
changed = changed + 1;
end
end
%% check convergence
if p1_converged && changed <= N*0.001
break;
else
step = step + 1;
end
end
end
function d2 = distances2(X, mu)
K = size(mu,2);
N = size(X,2);
d2 = zeros(K,N);
for j = 1 : K
d2(j,:) = sum((X - repmat(mu(:,j),1,N)).^2,1);
end
end
function mu = kpp( X,K )
% kmeans++ init
D = size(X,1); %No. of r.v.
N = size(X,2); %No. of observations
mu = zeros(D, K);
mu(:,1) = X(:,round(rand(1) * (size(X, 2)-1)+1));
for k = 2 : K
% computing distances between centroids and observations
d2 = distances2(X, mu(1:k-1));
% assignment
[min_dist, ~] = min(d2,[],1);
% select new centroids by selecting point with the cumulative dist
% value (distance) larger than random value (falls in range between
% dist(n-1) : dist(n), dist(0)= 0)
rv = sum(min_dist) * rand(1);
for n = 1 : N
if min_dist(n) >= rv
mu(:,k) = X(:,n);
break;
else
rv = rv - min_dist(n);
end
end
end
end

All my weights for gradient descent become 0 on feature expansion

I have 2 features which I expand to contain all possible combinations of the two features under order 6. When I do MATLAB's fminunc, it returns a weight vector where all elements are 0.
The dataset is here
clear all;
clc;
data = load("P2-data1.txt");
m = length(data);
para = 0; % regularization parameter
%% Augment Feature
y = data(:,3);
new_data = newfeature(data(:,1), data(:,2), 3);
[~, n] = size(new_data);
betas1 = zeros(n,1); % initial weights
options = optimset('GradObj', 'on', 'MaxIter', 400);
[beta_new, cost] = fminunc(#(t)(regucostfunction(t, new_data, y, para)), betas1, options);
fprintf('Cost at theta found by fminunc: %f\n', cost);
fprintf('theta: \n');
fprintf(' %f \n', beta_new); % get all 0 here
% Compute accuracy on our training set
p_new = predict(beta_new, new_data);
fprintf('Train Accuracy after feature augmentation: %f\n', mean(double(p_new == y)) * 100);
fprintf('\n');
%% the functions are defined below
function g = sigmoid(z) % running properly
g = zeros(size(z));
g=ones(size(z))./(ones(size(z))+exp(-z));
end
function [J,grad] = regucostfunction(theta,x,y,para) % CalculateCost(x1,betas1,y);
m = length(y); % number of training examples
J = 0;
grad = zeros(size(theta));
hyp = sigmoid(x*theta);
err = (hyp - y)';
grad = (1/m)*(err)*x;
sum = 0;
for k = 2:length(theta)
sum = sum+theta(k)^2;
end
J = (1/m)*((-y' * log(hyp) - (1 - y)' * log(1 - hyp)) + para*(sum) );
end
function p = predict(theta, X)
m = size(X, 1); % Number of training examples
p = zeros(m, 1);
index = find(sigmoid(theta'*X') >= 0.5);
p(index,1) = 1;
end
function out = newfeature(X1, X2, degree)
out = ones(size(X1(:,1)));
for i = 1:degree
for j = 0:i
out(:, end+1) = (X1.^(i-j)).*(X2.^j);
end
end
end
data contains 2 columns of rows followed by a third column of 0/1 values.
The functions used are: newfeature returns the expanded features and regucostfunction computes the cost. When I did the same approach with the default features, it worked and I think the problem here has to do with some coding issue.

Matlab error: Undefined function 'dmod' for input arguments of type 'double'. How come there is no dmod function as it should come with Matlab?

I have been working on some exam and need to do an exercise involving some frequency shift keying. That is why I use dmod function from Matlab - it comes with Matlab. But as I write in my console
yfsk=dmod([1 0], 3, 0.5, 100,'fsk', 2, 1);
it gives me this
`Undefined function 'dmod' for input arguments of type 'double'.
I have also tried doc dmod and it says 'page not found' in matlab help window.
Do you know wheter this is because I didn't install all the matlab packages or this function is not suported with matlab 2012a?
Thank you
This is gonna be helpful:
function [y, t] = dmod(x, Fc, Fd, Fs, method, M, opt2, opt3)
%DMOD
%
%WARNING: This is an obsolete function and may be removed in the future.
% Please use MODEM.PAMMOD, MODEM.QAMMOD, MODEM.GENQAMMOD, FSKMOD,
% MODEM.PSKMOD, or MODEM.MSKMOD instead.
% Y = DMOD(X, Fc, Fd, Fs, METHOD...) modulates the message signal X
% with carrier frequency Fc (Hz) and symbol frequency Fd (Hz). The
% sample frequency of Y is Fs (Hz), where Fs > Fc and where Fs/Fd is
% a positive integer. For information about METHOD and subsequent
% parameters, and about using a specific modulation technique,
% type one of these commands at the MATLAB prompt:
%
% FOR DETAILS, TYPE MODULATION TECHNIQUE
% dmod ask % M-ary amplitude shift keying modulation
% dmod psk % M-ary phase shift keying modulation
% dmod qask % M-ary quadrature amplitude shift keying
% % modulation
% dmod fsk % M-ary frequency shift keying modulation
% dmod msk % Minimum shift keying modulation
%
% For baseband simulation, use DMODCE. To plot signal constellations,
% use MODMAP.
%
% See also DDEMOD, DMODCE, DDEMODCE, MODMAP, AMOD, ADEMOD.
% Copyright 1996-2007 The MathWorks, Inc.
% $Revision: 1.1.6.5 $ $Date: 2007/06/08 15:53:47 $
warnobsolete(mfilename, 'Please use MODEM.PAMMOD, MODEM.QAMMOD, MODEM.GENQAMMOD, FSKMOD, MODEM.PSKMOD, or MODEM.MSKMOD instead.');
swqaskenco = warning('off', 'comm:obsolete:qaskenco');
swapkconst = warning('off', 'comm:obsolete:apkconst');
swmodmap = warning('off', 'comm:obsolete:modmap');
swamod = warning('off', 'comm:obsolete:amod');
opt_pos = 6; % position of 1st optional parameter
if nargout > 0
y = []; t = [];
end
if nargin < 1
feval('help','dmod')
return;
elseif isstr(x)
method = lower(deblank(x));
if length(method) < 3
error('Invalid method option for DMOD.')
end
if nargin == 1
% help lines for individual modulation method.
addition = 'See also DDEMOD, DMODCE, DDEMODCE, MODMAP, AMOD, ADEMOD.';
if method(1:3) == 'qas'
callhelp('dmod.hlp', method(1:4), addition);
else
callhelp('dmod.hlp', method(1:3), addition);
end
else
% plot constellation, make a shift.
opt_pos = opt_pos - 3;
M = Fc;
if nargin >= opt_pos
opt2 = Fd;
else
modmap(method, M);
return;
end
if nargin >= opt_pos+1
opt3 = Fs;
else
modmap(method, M, opt2);
return;
end
modmap(method, M, opt2, opt3); % plot constellation
end
return;
end
if (nargin < 4)
error('Usage: Y = DMOD(X, Fc, Fd, Fs, METHOD, OPT1, OPT2, OPT3) for passband modulation');
elseif nargin < opt_pos-1
method = 'samp';
else
method = lower(method);
end
len_x = length(x);
if length(Fs) > 1
ini_phase = Fs(2);
Fs = Fs(1);
else
ini_phase = 0; % default initial phase
end
if ~isfinite(Fs) | ~isreal(Fs) | Fs<=0
error('Fs must be a positive number.');
elseif length(Fd)~=1 | ~isfinite(Fd) | ~isreal(Fd) | Fd<=0
error('Fd must be a positive number.');
else
FsDFd = Fs/Fd; % oversampling rate
if ceil(FsDFd) ~= FsDFd
error('Fs/Fd must be a positive integer.');
end
end
if length(Fc) ~= 1 | ~isfinite(Fc) | ~isreal(Fc) | Fc <= 0
error('Fc must be a positive number. For baseband modulation, use DMODCE.');
elseif Fs/Fc < 2
warning('Fs/Fc must be much larger than 2 for accurate simulation.');
end
% determine M
if isempty(findstr(method, '/arb')) & isempty(findstr(method, '/cir'))
if nargin < opt_pos
M = max(max(x)) + 1;
M = 2^(ceil(log(M)/log(2)));
M = max(2, M);
elseif length(M) ~= 1 | ~isfinite(M) | ~isreal(M) | M <= 0 | ceil(M) ~= M
error('Alphabet size M must be a positive integer.');
end
end
if isempty(x)
y = [];
return;
end
[r, c] = size(x);
if r == 1
x = x(:);
len_x = c;
else
len_x = r;
end
% expand x from Fd to Fs.
if isempty(findstr(method, '/nomap'))
if ~isreal(x) | all(ceil(x)~=x)
error('Elements of input X must be integers in [0, M-1].');
end
yy = [];
for i = 1 : size(x, 2)
tmp = x(:, ones(1, FsDFd)*i)';
yy = [yy tmp(:)];
end
x = yy;
clear yy tmp;
end
if strncmpi(method, 'ask', 3)
if isempty(findstr(method, '/nomap'))
% --- Check that the data does not exceed the limits defined by M
if (min(min(x)) < 0) | (max(max(x)) > (M-1))
error('An element in input X is outside the permitted range.');
end
y = (x - (M - 1) / 2 ) * 2 / (M - 1);
else
y = x;
end
[y, t] = amod(y, Fc, [Fs, ini_phase], 'amdsb-sc');
elseif strncmpi(method, 'fsk', 3)
if nargin < opt_pos + 1
Tone = Fd;
else
Tone = opt2;
end
if (min(min(x)) < 0) | (max(max(x)) > (M-1))
error('An element in input X is outside the permitted range.');
end
[len_y, wid_y] = size(x);
t = (0:1/Fs:((len_y-1)/Fs))'; % column vector with all the time samples
t = t(:, ones(1, wid_y)); % replicate time vector for multi-channel operation
osc_freqs = pi*[-(M-1):2:(M-1)]*Tone;
osc_output = (0:1/Fs:((len_y-1)/Fs))'*osc_freqs;
mod_phase = zeros(size(x))+ini_phase;
for index = 1:M
mod_phase = mod_phase + (osc_output(:,index)*ones(1,wid_y)).*(x==index-1);
end
y = cos(2*pi*Fc*t+mod_phase);
elseif strncmpi(method, 'psk', 3)
% PSK is a special case of QASK.
[len_y, wid_y] = size(x);
t = (0:1/Fs:((len_y-1)/Fs))';
if findstr(method, '/nomap')
y = dmod(x, Fc, Fs, [Fs, ini_phase], 'qask/cir/nomap', M);
else
y = dmod(x, Fc, Fs, [Fs, ini_phase], 'qask/cir', M);
end
elseif strncmpi(method, 'msk', 3)
M = 2;
Tone = Fd/2;
if isempty(findstr(method, '/nomap'))
% Check that the data is binary
if (min(min(x)) < 0) | (max(max(x)) > (1))
error('An element in input X is outside the permitted range.');
end
x = (x-1/2) * Tone;
end
[len_y, wid_y] = size(x);
t = (0:1/Fs:((len_y-1)/Fs))'; % column vector with all the time samples
t = t(:, ones(1, wid_y)); % replicate time vector for multi-channel operation
x = 2 * pi * x / Fs; % scale the input frequency vector by the sampling frequency to find the incremental phase
x = [0; x(1:end-1)];
y = cos(2*pi*Fc*t+cumsum(x)+ini_phase);
elseif (strncmpi(method, 'qask', 4) | strncmpi(method, 'qam', 3) |...
strncmpi(method, 'qsk', 3) )
if findstr(method,'nomap')
[y, t] = amod(x, Fc, [Fs, ini_phase], 'qam');
else
if findstr(method, '/ar') % arbitrary constellation
if nargin < opt_pos + 1
error('Incorrect format for METHOD=''qask/arbitrary''.');
end
I = M;
Q = opt2;
M = length(I);
% leave to the end for processing
CMPLEX = I + j*Q;
elseif findstr(method, '/ci') % circular constellation
if nargin < opt_pos
error('Incorrect format for METHOD=''qask/circle''.');
end
NIC = M;
M = length(NIC);
if nargin < opt_pos+1
AIC = [1 : M];
else
AIC = opt2;
end
if nargin < opt_pos + 2
PIC = NIC * 0;
else
PIC = opt3;
end
CMPLEX = apkconst(NIC, AIC, PIC);
M = sum(NIC);
else % square constellation
[I, Q] = qaskenco(M);
CMPLEX = I + j * Q;
end
y = [];
x = x + 1;
% --- Check that the data does not exceed the limits defined by M
if (min(min(x)) < 1) | (max(max(x)) > M)
error('An element in input X is outside the permitted range.');
end
for i = 1 : size(x, 2)
tmp = CMPLEX(x(:, i));
y = [y tmp(:)];
end
ind_y = [1: size(y, 2)]';
ind_y = [ind_y, ind_y+size(y, 2)]';
ind_y = ind_y(:);
y = [real(y) imag(y)];
y = y(:, ind_y);
[y, t] = amod(y, Fc, [Fs, ini_phase], 'qam');
end
elseif strncmpi(method, 'samp', 4)
% This is for converting an input signal from sampling frequency Fd
% to sampling frequency Fs.
[len_y, wid_y] = size(x);
t = (0:1/Fs:((len_y-1)/Fs))';
y = x;
else % invalid method
error(sprintf(['You have used an invalid method.\n',...
'The method should be one of the following strings:\n',...
'\t''ask'' Amplitude shift keying modulation;\n',...
'\t''psk'' Phase shift keying modulation;\n',...
'\t''qask'' Quadrature amplitude shift-keying modulation, square constellation;\n',...
'\t''qask/cir'' Quadrature amplitude shift-keying modulation, circle constellation;\n',...
'\t''qask/arb'' Quadrature amplitude shift-keying modulation, user defined constellation;\n',...
'\t''fsk'' Frequency shift keying modulation;\n',...
'\t''msk'' Minimum shift keying modulation.']));
end
if r==1 & ~isempty(y)
y = y.';
end
warning(swqaskenco);
warning(swapkconst);
warning(swmodmap);
warning(swamod);
% [EOF]
I do believe that dmod function (Communication Toolbox) has been abandoned in the latest MATLAB releases.
It looks like dmod is no more :-)
Here is the link that says it was removed:
http://www.mathworks.com/help/comm/release-notes.html?searchHighlight=dmod
It should be replaced wit with comm.FSKModulator System object
I think you may be looking for the demodulation function (demod) from the signal processing toolbox.
http://www.mathworks.com.au/help/signal/ref/demod.html

Matlab NaN and Inf issue

So, I'm implementing the EM algorithm in Matlab, but my matrices quickly end up contaminated by NaN and Inf values. I think it might be caused by matrix inversions, but I'm not sure that's the only reason.
Here is the code:
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
This iterates until convergence (which never happens due to my issue) and calls smoother.m at each iteration:
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
The NaNs and Infs start popping around the ~8th iteration.
I guess in there somewhere I'm doing something unholy with my matrices, but I really have no clue about what's wrong. I trust your expertise.
Thanks in advance for the help.
Rody :
Here is how I generate the data (it's not "real world" data yet, just some test data generated to check that nothing goes wront) :
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
Dan :
You're right. I indeed lack the math background to really understand how the formulas are derived. I know it doesn't help, but I'm not sure I can remedy that for the time being. :/
Rody : Yes indeed, I arrived at the same conclusion. But I really have no clue what makes it go wrong like that.
Here is a link to the paper :
http://www.stat.pitt.edu/stoffer/em.pdf
The formulas for the smoother are all at the very end, in the appendix. Thanks for your time so far.
As the user appears to have inserted the answer into his question I will post it here:
As mentioned by #Rody the cause of the problem was that the use of inv created NaN or Inf values.
The user 'solved' this by using pinv instead.