复杂表达式的简化
Simplification of a complex expression
我有一个复杂的 MATLAB 表达式,我想对其进行简化,以便我能够真正理解它。
g = repmat(log(p), [size(x, 1), 1])
for i = 1:size(mu, 1)
g(:, i) = g(:, i) - sum(log(sigma(i, :)));
g(:, i) = g(:, i) - sum(bsxfun(@rdivide, bsxfun(@minus, x, mu(i, :)).^2, 2*sigma(i, :).^2), 2);
end
p=1x2
sigma=2x2
mu=2x2
x=30x2
基本上这些 bsxfun
函数让我很困惑。我想用简单的 for
循环的形式来表达它。
我试过这样的事情:
[m,n] = size(x)
for i=1:m
for j=1:n
g(i,j)= log(p(j)) - sum(log(sigma(j))) - sum(data(i,j))... ;
end
end
不太确定如何从这一点继续,主要是错误和错误的结果!
我会向您解释 bsxfun
,因为将其换成 for
循环就像将汽车换成自行车在速度方面一样。
可以找到 bsxfun
的一般介绍 here in this fantastic answer by Divakar。
让我们把你的程序一段一段地删减:
bsxfun(@minus, x, mu(i, :))
这只是告诉您 x
中的每个元素都从 mu(i,:)
中的每个元素中减去 (@minus
)。现在这个 bsxfun
嵌套到另一个:
bsxfun(@rdivide, bsxfun(@minus, x, mu(i, :)).^2, 2*sigma(i, :).^2)
这个 bsxfun
分为两部分,因此 rdivide
。前面讨论的bsxfun
相减得到的每个元素除以2*sigma(i,:).^2
中的每个元素,就是一个数组
最后对整个东西取sum
,得到一个单一的值。对于 i
.
的每个实例,从 g(:,i)
的原始条目中减去
请注意,use i
or j
as a variable, so one of the improvements of that code should be to change i
to e.g. ii
or n
or whatever not built-in function; or, as Divakar was kind enough to show in 是非常糟糕的做法,只需完全摆脱所有循环即可。
显然问题中的代码可以用作很好的 bsxfun
和 permute
练习来向量化所有内容。我知道这与问题中的要求相反,但将其作为替代解决方案。
回来,要实际矢量化所有内容,您需要使用 permute
扩展维度并继续使用 bsxfun
。实现看起来像这样 -
%// Vectorize : "g(:, i) = g(:, i) - sum(log(sigma(i, :)))"
parte1 = bsxfun(@minus,g,sum(log(sigma),2).'); %//'
%// Vectorize : "bsxfun(@minus, x, mu(i, :)).^2"
parte2_1 = bsxfun(@minus,x,permute(mu,[3 2 1])).^2;
%// Vectorize : "bsxfun(@rdivide, ...*sigma(i, :).^2)"
parte2 = bsxfun(@rdivide,parte2_1,2*permute(sigma,[3 2 1]).^2);
%// Squeeze in dimensions of the BSXFUN extended array and subtract from parte1
g = parte1 - squeeze(sum(parte2,2));
我有一个复杂的 MATLAB 表达式,我想对其进行简化,以便我能够真正理解它。
g = repmat(log(p), [size(x, 1), 1])
for i = 1:size(mu, 1)
g(:, i) = g(:, i) - sum(log(sigma(i, :)));
g(:, i) = g(:, i) - sum(bsxfun(@rdivide, bsxfun(@minus, x, mu(i, :)).^2, 2*sigma(i, :).^2), 2);
end
p=1x2
sigma=2x2
mu=2x2
x=30x2
基本上这些 bsxfun
函数让我很困惑。我想用简单的 for
循环的形式来表达它。
我试过这样的事情:
[m,n] = size(x)
for i=1:m
for j=1:n
g(i,j)= log(p(j)) - sum(log(sigma(j))) - sum(data(i,j))... ;
end
end
不太确定如何从这一点继续,主要是错误和错误的结果!
我会向您解释 bsxfun
,因为将其换成 for
循环就像将汽车换成自行车在速度方面一样。
可以找到 bsxfun
的一般介绍 here in this fantastic answer by Divakar。
让我们把你的程序一段一段地删减:
bsxfun(@minus, x, mu(i, :))
这只是告诉您 x
中的每个元素都从 mu(i,:)
中的每个元素中减去 (@minus
)。现在这个 bsxfun
嵌套到另一个:
bsxfun(@rdivide, bsxfun(@minus, x, mu(i, :)).^2, 2*sigma(i, :).^2)
这个 bsxfun
分为两部分,因此 rdivide
。前面讨论的bsxfun
相减得到的每个元素除以2*sigma(i,:).^2
中的每个元素,就是一个数组
最后对整个东西取sum
,得到一个单一的值。对于 i
.
g(:,i)
的原始条目中减去
请注意,use i
or j
as a variable, so one of the improvements of that code should be to change i
to e.g. ii
or n
or whatever not built-in function; or, as Divakar was kind enough to show in
显然问题中的代码可以用作很好的 bsxfun
和 permute
练习来向量化所有内容。我知道这与问题中的要求相反,但将其作为替代解决方案。
回来,要实际矢量化所有内容,您需要使用 permute
扩展维度并继续使用 bsxfun
。实现看起来像这样 -
%// Vectorize : "g(:, i) = g(:, i) - sum(log(sigma(i, :)))"
parte1 = bsxfun(@minus,g,sum(log(sigma),2).'); %//'
%// Vectorize : "bsxfun(@minus, x, mu(i, :)).^2"
parte2_1 = bsxfun(@minus,x,permute(mu,[3 2 1])).^2;
%// Vectorize : "bsxfun(@rdivide, ...*sigma(i, :).^2)"
parte2 = bsxfun(@rdivide,parte2_1,2*permute(sigma,[3 2 1]).^2);
%// Squeeze in dimensions of the BSXFUN extended array and subtract from parte1
g = parte1 - squeeze(sum(parte2,2));