0

我正在尝试修改使用全局变量的其他人的代码并不断收到我无法弄清楚的错误。这是我第一次使用全局变量,所以我怀疑它与此有关。我收到此错误:

Attempt to reference field of non-structure array.

Error in likelihood (line 35)
X=ModelInfo.X;

这是我运行的代码:

clearvars -global
clearvars
global ModelInfo

%Pull in data from MySQL database
ModelInfo.X=.....   %76x2 double type
ModelInfo.y=.....   %76x1 double type

addpath('C:/.../Sampling Plans');
addpath('C:/.../Constructing a Surrogate');

%Number of variables
k=size(ModelInfo.X,2);
%Number of sample points
n=size(ModelInfo.X,1);
%Set upper and lower bounds for search of log theta
UpperTheta=ones(1,k).*2;
LowerTheta=ones(1,k).*-3;

%Run GA search of likelihood
[ModelInfo.Theta,MinNegLnLikelihood]=ga(@likelihood,k,[],[],[],[],LowerTheta,UpperTheta);

...引用外部函数可能性(由其他人编写):

function [NegLnLike,Psi,U]=likelihood(x)

global ModelInfo
X=ModelInfo.X;
y=ModelInfo.y;
theta=10.^x;
p=2; 
n=size(X,1);
one=ones(n,1);

% Pre-allocate memory
Psi=zeros(n,n);
% Build upper half of correlation matrix
for i=1:n
    for j=i+1:n
        Psi(i,j)=exp(-sum(theta.*abs(X(i,:)-X(j,:)).^p)); 
    end
end

% Add upper and lower halves and diagonal of ones plus 
% small number to reduce ill-conditioning
Psi=Psi+Psi'+eye(n)+eye(n).*eps; 

% Cholesky factorisation
[U,p]=chol(Psi);

% Use penalty if ill-conditioned
if p>0
    NegLnLike=1e4;
else

    % Sum lns of diagonal to find ln(abs(det(Psi)))
    LnDetPsi=2*sum(log(abs(diag(U))));

    % Use back-substitution of Cholesky instead of inverse
    mu=(one'*(U\(U'\y)))/(one'*(U\(U'\one)));
    SigmaSqr=((y-one*mu)'*(U\(U'\(y-one*mu))))/n;
    NegLnLike=-1*(-(n/2)*log(SigmaSqr) - 0.5*LnDetPsi);
end

更新:

想通了问题。我在开始时将 ModelInfo 声明为全局变量,然后在该%Pull in data from MySQL database部分中我创建了一个数据库连接,然后使用该命令清除了一些我们不再需要的变量clearvars -except,但我没有在该列表中包含 ModelInfo。之后,我将数据放入 ModelInfo。由于它是全局的,我猜它删除了本地副本或全局副本(不太确定),但它仍然出现在工作区的变量列表中并且isstruct(ModelInfo)仍然返回 1 ......所以显然没有任何迹象表明存在问题除了错误。

4

1 回答 1

1

如果这确实是您运行的代码:

%Pull in data from MySQL database
ModelInfo.X=.....   %76x2 double type
ModelInfo.y=.....   %76x1 double type

我怀疑它与全局变量有什么关系。您应该有一些某种数据而不是 5 个点.....,以使任何代码都能正常工作(因为上面的注释表示“从...中提取数据”)。我也会尝试以评论建议的形式制作这些数据,如果它不属于同一类,即制作它double并具有提到的大小。

例如,试着看看用 this 替换这些行是否能让你的代码工作

ModelInfo.X=rand(76,2)   %76x2 double type
ModelInfo.y=rand(76,1)   %76x1 double type
于 2013-01-29T23:09:08.953 回答