Matlab 编码器导致 bsxfun 中的矩阵扩展出现问题
Matlab coder causing problems with matrix expansion in bsxfun
我一直在尝试从一个本科生为我们编写的代码中向量化一些操作。他使用了丑陋的嵌套循环,我试图将其更改为 bsxfun 调用。当我按原样使用此函数时这有效,但是当我尝试使用编码器对其进行 mex 编译时,出现错误。
编辑:我意识到我应该澄清代码的某些部分。 S、W 和 N 是 nxn 矩阵,表示对成对比较 ij 的偏好。 mu 是包含绝对评级重建的(预测)分数的行向量。
要查看代码的作用,您可能需要查看页面的最底部。
原代码如下:
for i = 1:n
for j = i:n
if i~= j
mu = x(i) - x(j);
md1 = normcdf(-delta1, mu); %minus d0
md0 = normcdf(-delta0, mu);
d0 = normcdf( delta0, mu);
d1 = normcdf( delta1, mu);
Y = Y + S(i,j) .* log(1 - d1) + ...
W(i,j) .* log(d1 - d0) + ...
N(i,j) .* log(d0 - md0) + ...
W(j,i) .* log(md0 - md1) + ...
S(j,i) .* log(md1);
end
end
end
Y = -Y; %this will be used in fminsearch, therefore the negative sign
我为此编写了一个快速但肮脏的矢量化解决方案:
diffs = bsxfun(@minus,x,x');
% create the deltas array augmented by -Inf and Inf for easy diff calculation
deltass = sort([-Inf, Inf, deltas, -1*deltas]);
deltass = reshape(deltass, [1, 1, length(deltass)]);
normcdfs = diff(1-bsxfun(@normcdfupper, diffs, deltass), 1, 3);
normcdfs(repmat(logical(tril(ones(size(normcdfs(:,:,1))))),[1,1,length(deltass)-1])) = 1;
Y = -sum(sum(sum(normcdfs_input.*log(normcdfs))));
编辑:normcdfupper 是一个包装器 class 我写道调用 normcdf(diff, delta, 'upper') 因为我 运行 遇到了这个问题,尾端可能会导致错误。
就像我说的,这在我的日常使用中效果很好。但是由于混合旧的嵌套 for 循环版本带来了巨大的加速,我尝试用这个加速版本做同样的事情,只是在编码器中遇到以下错误:
Expansion is only supported along dimensions where one input argument or the other has a fixed length of 1.
Error in lik_ml (line 27)
normcdfs = diff(1-bsxfun(@normcdfupper,diffs,deltass),1,3);
diffs 是一个 :infx:inf double,而 deltass 是一个 1x1x:inf double。编码器告诉我:
diffs
deltass
如果有人能帮我解决这个错误信息,我将不胜感激。
编辑:一些测试代码:
clear all;
% rng(322);
delta0 = 1;
delta1 = 2;
deltas = [delta0, delta1];
sigma = 0.5;
options = 5;
maxVotes = 10000;
voteStep = 3;
initialVoteStep = 3;
raw_mu = rand(1,options);
mu = sort(zscore(raw_mu));
S = zeros(options);
W = zeros(options);
N = zeros(options);
for i = 1:options
for j = i:options
if i ~= j
S(i,j) = 1 - normcdf(delta1, mu(i)-mu(j));
W(i,j) = normcdf( delta1, mu(i)-mu(j)) - normcdf( delta0, mu(i)-mu(j));
N(i,j) = normcdf( delta0, mu(i)-mu(j)) - normcdf(-delta0, mu(i)-mu(j));
W(j,i) = normcdf(-delta0, mu(i)-mu(j)) - normcdf(-delta1, mu(i)-mu(j));
S(j,i) = normcdf(-delta1, mu(i)-mu(j));
end
end
end
diffs = bsxfun(@minus,mu,mu');
deltass = sort([-Inf, Inf, deltas, -1*deltas]);
deltass = reshape(deltass,[1,1,length(deltass)]);
normcdfs = diff(bsxfun(@(x,y) normcdf(y,x),diffs,deltass),1,3);
这是 for 循环的矢量化版本
[I,J] = meshgrid(1:n);
idx = I<J;
I = I(idx);
J = J(idx);
IJ = sub2ind([n n],I,J);
JI = sub2ind([n n],J,I);
mu = x(I)-x(J);
md1 = normcdf(-delta1, mu).';
md0 = normcdf(-delta0, mu).';
d0 = normcdf( delta0, mu).';
d1 = normcdf( delta1, mu).';
Y = sum(S(IJ) .* log(max(0,1 - d1)) + ...
W(IJ) .* log(max(0,d1 - d0)) + ...
N(IJ) .* log(max(0,d0 - md0)) + ...
W(JI) .* log(max(0,md0 - md1)) + ...
S(JI) .* log(max(0,md1)));
我一直在尝试从一个本科生为我们编写的代码中向量化一些操作。他使用了丑陋的嵌套循环,我试图将其更改为 bsxfun 调用。当我按原样使用此函数时这有效,但是当我尝试使用编码器对其进行 mex 编译时,出现错误。
编辑:我意识到我应该澄清代码的某些部分。 S、W 和 N 是 nxn 矩阵,表示对成对比较 ij 的偏好。 mu 是包含绝对评级重建的(预测)分数的行向量。
要查看代码的作用,您可能需要查看页面的最底部。
原代码如下:
for i = 1:n
for j = i:n
if i~= j
mu = x(i) - x(j);
md1 = normcdf(-delta1, mu); %minus d0
md0 = normcdf(-delta0, mu);
d0 = normcdf( delta0, mu);
d1 = normcdf( delta1, mu);
Y = Y + S(i,j) .* log(1 - d1) + ...
W(i,j) .* log(d1 - d0) + ...
N(i,j) .* log(d0 - md0) + ...
W(j,i) .* log(md0 - md1) + ...
S(j,i) .* log(md1);
end
end
end
Y = -Y; %this will be used in fminsearch, therefore the negative sign
我为此编写了一个快速但肮脏的矢量化解决方案:
diffs = bsxfun(@minus,x,x');
% create the deltas array augmented by -Inf and Inf for easy diff calculation
deltass = sort([-Inf, Inf, deltas, -1*deltas]);
deltass = reshape(deltass, [1, 1, length(deltass)]);
normcdfs = diff(1-bsxfun(@normcdfupper, diffs, deltass), 1, 3);
normcdfs(repmat(logical(tril(ones(size(normcdfs(:,:,1))))),[1,1,length(deltass)-1])) = 1;
Y = -sum(sum(sum(normcdfs_input.*log(normcdfs))));
编辑:normcdfupper 是一个包装器 class 我写道调用 normcdf(diff, delta, 'upper') 因为我 运行 遇到了这个问题,尾端可能会导致错误。
就像我说的,这在我的日常使用中效果很好。但是由于混合旧的嵌套 for 循环版本带来了巨大的加速,我尝试用这个加速版本做同样的事情,只是在编码器中遇到以下错误:
Expansion is only supported along dimensions where one input argument or the other has a fixed length of 1.
Error in lik_ml (line 27)
normcdfs = diff(1-bsxfun(@normcdfupper,diffs,deltass),1,3);
diffs 是一个 :infx:inf double,而 deltass 是一个 1x1x:inf double。编码器告诉我:
diffs deltass
如果有人能帮我解决这个错误信息,我将不胜感激。
编辑:一些测试代码:
clear all;
% rng(322);
delta0 = 1;
delta1 = 2;
deltas = [delta0, delta1];
sigma = 0.5;
options = 5;
maxVotes = 10000;
voteStep = 3;
initialVoteStep = 3;
raw_mu = rand(1,options);
mu = sort(zscore(raw_mu));
S = zeros(options);
W = zeros(options);
N = zeros(options);
for i = 1:options
for j = i:options
if i ~= j
S(i,j) = 1 - normcdf(delta1, mu(i)-mu(j));
W(i,j) = normcdf( delta1, mu(i)-mu(j)) - normcdf( delta0, mu(i)-mu(j));
N(i,j) = normcdf( delta0, mu(i)-mu(j)) - normcdf(-delta0, mu(i)-mu(j));
W(j,i) = normcdf(-delta0, mu(i)-mu(j)) - normcdf(-delta1, mu(i)-mu(j));
S(j,i) = normcdf(-delta1, mu(i)-mu(j));
end
end
end
diffs = bsxfun(@minus,mu,mu');
deltass = sort([-Inf, Inf, deltas, -1*deltas]);
deltass = reshape(deltass,[1,1,length(deltass)]);
normcdfs = diff(bsxfun(@(x,y) normcdf(y,x),diffs,deltass),1,3);
这是 for 循环的矢量化版本
[I,J] = meshgrid(1:n);
idx = I<J;
I = I(idx);
J = J(idx);
IJ = sub2ind([n n],I,J);
JI = sub2ind([n n],J,I);
mu = x(I)-x(J);
md1 = normcdf(-delta1, mu).';
md0 = normcdf(-delta0, mu).';
d0 = normcdf( delta0, mu).';
d1 = normcdf( delta1, mu).';
Y = sum(S(IJ) .* log(max(0,1 - d1)) + ...
W(IJ) .* log(max(0,d1 - d0)) + ...
N(IJ) .* log(max(0,d0 - md0)) + ...
W(JI) .* log(max(0,md0 - md1)) + ...
S(JI) .* log(max(0,md1)));