程序在 Matlab 中正常运行,但在并行工具箱中不起作用



我最近在这里询问了一个相关的问题:

https://stackoverflow.com/questions/21171836/storing-matrix-output-in-higher-dimensional-matrix

我现在只想在并行配置中运行代码,但当我这样做时,我会得到以下错误:

在598使用===>parallel_function时出错===>OIRE中的错误,位于136未定义的函数或变量"best_index"。

73处的OIRE_MSE_test中存在错误parfor t=1:nsims

===>OIRE_MSE_test在95时出错[b_OIRE OIRE_opt_b(:,:,t)]=OIRE(y,x,iter);

只要我放下matlab池打开/关闭和parfor命令,代码就可以正常工作。为什么这不会在并行工具箱中运行?

clc;
n=100;
p=7; 
alpha1=0.999999;
error_vol=0.1;
iter=1000;
nsims=200;
OIRE_opt_b=zeros(7,3,nsims);
OIRE_opt_MSE=zeros(1,3,nsims);
OIRE_opt_index=zeros(1,3,nsims);
GIREI_opt_b=zeros(7,3,nsims);
GIREI_opt_MSE=zeros(1,3,nsims);
GIREI_opt_index=zeros(1,3,nsims);
GIREII_opt_b=zeros(7,3,nsims);
GIREII_opt_MSE=zeros(1,3,nsims);
GIREII_opt_index=zeros(1,3,nsims);
LRRE_opt_b=zeros(7,3,nsims);
LRRE_opt_MSE=zeros(1,3,nsims);
LRRE_opt_index=zeros(1,3,nsims);

matlabpool open

x=zeros(n,p);
for i=1:n
z_i4=normrnd(0,1);
x(i,p)=z_i4;
for j=1:p-1
x(i,j)=x(i,j)+alpha1*z_i4;
x(i,j)= x(i,j)+(1-alpha1^2)^(0.5)*normrnd(0,1);
end  
end
b_act=[5;1;10;-20;200;30;-2];
parfor t=1:nsims
residuals=normrnd(0,error_vol,n,1);
y=x*b_act + residuals;
y_store(:,t)=y;
y=y_store(:,t);
[b_OIRE OIRE_opt_b(:,:,t) OIRE_opt_MSE(:,:,t) OIRE_opt_index(:,:,t)]=OIRE(y,x,iter);
end

调用函数

function [b_OIRE OIRE_opt_b OIRE_opt_MSE OIRE_opt_index]=OIRE(y,x,iter)  
dim=1;
pool=[10,100,1000,10000,1000000,10000000];
count=0;
[n, p]=size(x);
b=xy; 
b_OIRE = b; % [#1] initialize b_LRRE as b
sigma_sq=((y-x*b)'*(y-x*b))/(n-p); %'
b_act=[1;0;1;1;0;1;1];
econFlag=0;
[U,sigma,V] = svd(x,econFlag);

U1=U(:,1:p);
d=zeros(p,1);
d=diag(d);
alpha=V'*b_OIRE; %'
Delta=sigma.^1;        
Delta=diag(Delta);
f=Delta.*alpha;
F=diag(f);
Theta=sum(f);
c=p^2*sigma_sq+p*Theta^2;
g=Theta*sum(alpha);
I=ones(p,1);
a=sigma_sq*I+Theta*f;
b=F*alpha;
k=zeros(p,1);
A=sigma_sq*eye(p)+F.^2;
varRho=(g-a'*pinv(A)*b)*pinv(c-a'*pinv(A)*a); 
k=pinv(A)*b-varRho*pinv(A)*a;
K=diag(k);
D=varRho*I*I';
b_OIRE= V*(K+D)*U1'*y;

MSE=(k'*A*k)+(2*varRho*a'*k)-(2*b'*k)+(c*varRho^2)-(2*g*varRho)+(alpha'*alpha);

best_OIRE_MSE=MSE;
best_b_OIRE=b_OIRE;

for jj=1:iter           % [## "iter" denotes the iteration number]
alpha=V'*b_OIRE;        %'
Delta=sigma.^1;         % [Error! not sigma.^2 but sigma.^1]
Delta=diag(Delta);
f=Delta.*alpha;
F=diag(f);
Theta=sum(f);
c=p^2*sigma_sq+p*Theta^2;
g=Theta*sum(alpha);
I=ones(p,1);
a=sigma_sq*I+Theta*f;
b=F*alpha;
k=zeros(p,1);
A=sigma_sq*eye(p)+F.^2;
varRho=(g-a'*pinv(A)*b)*pinv(c-a'*pinv(A)*a);
k=pinv(A)*b-varRho*pinv(A)*a;
K=diag(k);
D=varRho*I*I';
b_OIRE= V*(K+D)*U1'*y;
MSE=(k'*A*k)+(2*varRho*a'*k)-(2*b'*k)+(c*varRho^2)-(2*g*varRho)+(alpha'*alpha);
if(MSE<best_OIRE_MSE)
best_b_OIRE=b_OIRE;
best_OIRE_MSE=MSE;
best_index=jj+1;
end
if( any(jj == pool))
count=count+1;
OIRE_opt_b(:,count)=best_b_OIRE;
OIRE_opt_MSE(count)=best_OIRE_MSE;
OIRE_opt_index(count)=best_index;
end

end

end
matlabpool close

您的问题是best_index从未在MSE<best_OIRE_MSEif语句之外的任何地方定义。

我怀疑这就是正在发生的事情。当您在没有parfor的情况下运行代码时,它会按顺序迭代(即jj==1总是出现在jj==2之前等)。如果不仔细查看代码的复杂性,我怀疑这意味着MSE<best_OIRE_MSEany(jj==pool)为真之前(或在与之相同的迭代中)总是为真。这意味着,当代码到达any(jj == pool)if语句时,best_index将始终被设置。

问题在于parfor不能保证循环的执行顺序。CCD_ 10可能在CCD_ 11之前运行。这意味着不能保证best_index在到达any(jj == pool)if语句时会被定义,因此会出现错误。

我的建议是将主parfor循环之外的best_index定义为-1,然后忽略OIRE_opt_index为负数的任何情况。

最新更新