基于矢量的每个元素的矢量创建 - Matlab

时间:2018-04-06 14:32:35

标签: matlab

我想为一个向量的每个元素应用一个线空间函数,并在最后创建一个完整的向量,是否有一些方便的方法呢?

具体来说,我想用矩阵 A 创建矩阵 B 而不使用使用循环,其中 A = [1; 2; 3; 4] B = [1; 1; 2; 1; 2; 3; 1; 2; 3; 4]

如您所见,如果向量中的第三个元素是3,那么"第三个向量"在输出向量中 B 将为[1:1:3]。我想要的步骤是固定的,对于任何元素都是精确的。

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:3)

由于B的动态特性,没有任何循环就无法做到这一点。在这种情况下,我不会回避循环 - 特别是对于更新版本的MATLAB及其改进的JIT编译器。现在循环比矢量化操作更具竞争力,具体取决于你想要做什么。

最简单的方法是循环遍历A和冒号运算符的所有值,并从1转到A中的每个值。

这样的事情会起作用:

A = [1; 2; 3; 4];
B = [];

for v = 1 : numel(A)
    B = [B; (1:A(v)).'];
end

在每次迭代中,我们在A中找到一个值,并创建一个从1到该值的向量。我们将所有这些连接成一个向量。请注意,不会执行错误检查,因此我们假设A中的每个值都大于或等于1.

如果您热衷于单线,可以使用arrayfun来创建一堆单元格数组并将它们挤压在一起,但性能明智这可能不是最佳解决方案:

A = [1; 2; 3; 4];
B = cell2mat(arrayfun(@(x) (1:x).', A, 'un', 0));

arrayfun接受一个函数来对A中的每个输入元素进行操作,因此该函数将创建一个从1到所需值的列向量。 unUniformOutput的缩写,它设置为0意味着输出不均匀,因此我们要输出一堆单元格数组 - 每个矢量一个单元数组一个。创造了。最后,cell2mat将所有单元阵列挤压在一起以创建单个列向量。它更优雅,但性能方面可能并非如此,因为有很多开销。

答案 1 :(得分:3)

以下两种避免循环的方法。

  • 使用bsxfun:这种方法是记忆 - (也许是时间)效率低下:

    t = 1:max(A);
    B = nonzeros(bsxfun(@times, t.', bsxfun(@le, t.', t)));
    
  • 使用cumsum:这样可以提高内存效率,但有点复杂:

    A = nonzeros(A); % remove zeros, if any
    B = ones(1, sum(A)); % initiallize
    B(cumsum(A(1:end-1))+1) = 1-A(1:end-1); % write appropriate values...
    B = cumsum(B).'; % ... so that the cumulative sum gives the desired output
    

循环可能是最好的方式:最简单,最清晰。

答案 2 :(得分:0)

您可以使用for循环执行此操作:

B = [];
for ii=1:size(A)
    B = [B;(1:A(ii))'];
end

结果

B = [1; 1; 2; 1; 2; 3; 1; 2; 3; 4]