gpt4 book ai didi

matlab - 向量化代码的性能,以从索引向量创建每行单个 1 的稀疏矩阵

转载 作者:太空宇宙 更新时间:2023-11-03 19:59:46 25 4
gpt4 key购买 nike

我有一个大列向量 y包含从 1 到 10 的整数值。我想将它转换为一个矩阵,其中每一行都充满了 0,除了在由 y 的相应行的值给出的索引处的 1 之外。 .

这个例子应该更清楚:

y = [3; 4; 1; 10; 9; 9; 4; 2; ...]

% gets converted to:

Y = [
0 0 1 0 0 0 0 0 0 0;
0 0 0 1 0 0 0 0 0 0;
1 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 1;
0 0 0 0 0 0 0 0 1 0;
0 0 0 0 0 0 0 0 1 0;
0 0 0 1 0 0 0 0 0 0;
0 1 0 0 0 0 0 0 0 0;
...
]

我为此编写了以下代码(有效):

m = length(y);
Y = zeros(m, 10);
for i = 1:m
Y(i, y(i)) = 1;
end

我知道有一些方法可以删除此代码中的 for 循环(矢量化)。 This post包含一些,包括类似的东西:

Y = full(sparse(1:length(y), y, ones(length(y),1)));

但我必须转换 y加倍以便能够使用它,结果实际上比我的“for”方法慢 3 倍,使用 10.000.000 作为 y 的长度.

  1. 对于非常大的 y,进行这种矢量化是否可能会带来更好的性能? ?我读过很多次矢量化计算会带来更好的性能(不仅在 MATLAB 中),但这种解决方案似乎会导致更多的计算。

  2. 在这个例子中,有没有办法实际提高 for 方法的性能?也许这里的问题只是对 double 而不是整数进行比较并不是最好的比较方法,但我找不到使用 sparse 的方法。否则。

最佳答案

下面是对 comapre 的测试:

function [t,v] = testIndicatorMatrix()
y = randi([1 10], [1e6 1], 'double');
funcs = {
@() func1(y);
@() func2(y);
@() func3(y);
@() func4(y);
};

t = cellfun(@timeit, funcs, 'Uniform',true);
v = cellfun(@feval, funcs, 'Uniform',false);
assert(isequal(v{:}))
end
function Y = func1(y)
m = numel(y);
Y = zeros(m, 10);
for i = 1:m
Y(i, y(i)) = 1;
end
end

function Y = func2(y)
m = numel(y);
Y = full(sparse(1:m, y, 1, m, 10, m));
end

function Y = func3(y)
m = numel(y);
Y = zeros(m,10);
Y(sub2ind([m,10], (1:m).', y)) = 1;
end

function Y = func4(y)
m = numel(y);
Y = zeros(m,10);
Y((y-1).*m + (1:m).') = 1;
end

我得到:

>> testIndicatorMatrix
ans =
0.0388
0.1712
0.0490
0.0430

这样一个简单的 for 循环可以在运行时进行动态 JIT 编译,并且运行速度非常快(甚至比向量化代码快一点)!

关于matlab - 向量化代码的性能,以从索引向量创建每行单个 1 的稀疏矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26703485/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com