2

Possible Duplicate: How to correct “Function definitions are not permitted at the prompt or in scripts”

Not surprisingly, if I try to run the following M script within the MATLAB I get the error

??? Error: File: kalmanmle.m Line: 47 Column: 1 Function definitions are not permitted in this context.

I am unsure if this can be run like the way I am. Or, how would I run this on the MATLAB command line?

clear all;

%  State space reprsentation to be forcasted by kalman filter
%   zhi(t+1) = F*zhi(t) + v(t+1)   --> unbobserved varaibles
%   v~N(0,Q)
%   y(t) = A'*x(t) + H'*zhi(t) + w(t)
%   w~N(0,R)

global y;
global x;
global Hvec;
%%----    Enter  Input parameters
F = 0.9;
Q = 0.1;
A = 2;
n = 100;
Hvec = zeros(n,1); %index returns process
indexshock = normal_rnd(0,0.1,n,1);
Hvec(1) = 0;
for i = 2:n,
    Hvec(i) = 0.95*Hvec(i-1) + indexshock(i);
end

%H = 0.3;
R = 0.05;

x = ones(n,1);
zhi = zeros(n,1);
y = zeros(n,1);
zhi(1) = 0;
v = normal_rnd(0,Q,n,1);
w = normal_rnd(0,R,n,1);

H = Hvec(1);
y(1) = A'*x(1) + H'*zhi(1) + w(1);
for i = 2:n,
    H = Hvec(i);
    zhi(i) = F*zhi(i-1) + v(i);
    y(i) = A'*x(i) + H'*zhi(i) + w(i);
end
%% ------------------
%test = [zhi y]

function ret = MyLikelihoodFn(p)
    global y;
    global x;
    global Hvec;
    F = p(1);
    Q = p(2)^2;
    A = p(3);
    R = p(4)^2;
    n = size(y,1);
    P = Q;
    Ezhi = 0;
    Ezhivec = zeros(n,1);
    Ezhivec(1) = Ezhi;
    tmpsum = 0;
    tmp1 = -(n/2)*log(2*pi);
    for i = 2:n,
        yt = y(i);
        xt = x(i);
        H = Hvec(i);
        Ezhi = F*Ezhi + F*P*H*inv(H'*P*H+R)*(yt-A'*xt-H'*Ezhi);
        P = F*P*F' - F*P*H*inv(H'*P*H+R)*H'*P*F' + Q;
        Ezhivec(i) = Ezhi;
        tmpmat = H'*P*H + R;
        tmp2 = -0.5*log(det(tmpmat));
        tmpmat2 = yt - A'*xt - H'*Ezhi;
        tmp3 = -0.5*tmpmat2'*inv(tmpmat)*tmpmat2;
        tmpsum = tmp1+tmp2+tmp3;
    end
    ret = -tmpsum;
endfunction

param = zeros(4,1);
param(1) = 0.2;
param(2) = 0.2;
param(3) = 1;
param(4) = 0.2;

resultparam = fmins('MyLikelihoodFn',param)

actualF = F
F = resultparam(1)
actualQ = Q
Q = resultparam(2)^2
actualA = A
A = resultparam(3)
actualR = R
R = resultparam(4)^2

n = size(y,1);
P = Q;
Ezhi = 0;
Ezhivec = zeros(n,1);
Ezhivec(1) = Ezhi;

for i = 2:n,
    yt = y(i);
    xt = x(i);
    H = Hvec(i);
    Ezhi = F*Ezhi + F*P*H*inv(H'*P*H+R)*(yt-A'*xt-H'*Ezhi);
    P = F*P*F' - F*P*H*inv(H'*P*H+R)*H'*P*F' + Q;
    Ezhivec(i) = Ezhi;
end
test = [zhi Ezhivec Hvec y];
tmp = 1:n;
%plot(tmp,zhi,'-',tmp,Ezhivec,'-',tmp,Hvec,'-',tmp,y,'-');
plot(tmp,zhi,'-',tmp,Ezhivec,'-');
Community
  • 1
  • 1
heavy rocker dude
  • 2,271
  • 8
  • 33
  • 47
  • Please try to use a code block for the code. It looks like a heap, and it is very difficult to read it. – John Alexiou May 12 '11 at 01:03
  • 1
    Also related: [What's the difference between a script and a function in MATLAB?](http://stackoverflow.com/questions/1695365/whats-the-difference-between-a-script-and-a-function-in-matlab), [In MATLAB, can I have a script and a function definition in the same file?](http://stackoverflow.com/questions/5363397/in-matlab-can-i-have-a-script-and-a-function-definition-in-the-same-file) – gnovice May 12 '11 at 02:56

2 Answers2

5

You can't define functions in script files (a .m file which isn't a function definition). They must be in an .m file of their own. This is annoying, but the way it is. For very short functions, you can make anonymous functions on the fly, but these are limited in their content:

 fun = @(params) STATEMENT;

 fun = @(x,y) x*y+sum(x^2-y^2);

Your example above is a bit too complex for this.

Alex
  • 5,863
  • 2
  • 29
  • 46
4

To expand on Alex's answer, you need to put your function MyLikelihoodFn(p) into a new file which must be called MyLikelihoodFn.m. Also, there is no endfunction keyword in MATLAB, it is just end.

If you do want to keep everything in one file, you have to turn your script into a function itself (by adding function functionnamewhichmatchesfilename as a first line) and move function ret=MyLikelihoodFn(p) to the very end of the file (right now it seems to be in the middle of the code of the script?). In this case you also won't need the clear all since a function always starts with its own clean workspace.

Jonas Heidelberg
  • 4,984
  • 1
  • 27
  • 41