MATLAB 错误“在此上下文中不允许函数定义。”
可能的重复: 如何更正“不允许在提示符下或脚本中定义函数”
毫不奇怪,如果我尝试在 MATLAB 中运行以下 M 脚本,我会收到错误
???错误:文件:kalmanmle.m 行:47 列:1 在此上下文中不允许函数定义。
我不确定这是否可以像我这样运行。或者,我如何在 MATLAB 命令行上运行它?
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,'-');
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,'-');
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不能在脚本文件(不是函数定义的 .m 文件)中定义函数。它们必须位于自己的 .m 文件中。这很烦人,但事实就是如此。对于非常短的函数,您可以即时创建匿名函数,但这些函数的内容有限:
上面的示例对此有点太复杂了。
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:
Your example above is a bit too complex for this.
要扩展 Alex 的答案,您需要将函数
MyLikelihoodFn(p)
放入一个新文件中,该文件必须名为MyLikelihoodFn.m
。另外,MATLAB 中没有endfunction
关键字,它只是end
。如果您确实希望将所有内容保留在一个文件中,则必须将脚本本身转换为函数(通过添加
function functionnamewhichmatchesfilename
作为第一行)并移动function ret=MyLikelihoodFn(p)
到文件的最末尾(现在它似乎位于脚本代码的中间?)。在这种情况下,您也不需要全部清除
,因为函数始终从其自己的干净工作区开始。To expand on Alex's answer, you need to put your function
MyLikelihoodFn(p)
into a new file which must be calledMyLikelihoodFn.m
. Also, there is noendfunction
keyword in MATLAB, it is justend
.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 movefunction 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 theclear all
since a function always starts with its own clean workspace.