【问题标题】:Make an n x n-1 matrix from 1 x n vector where the i-th row is the vector without the i-th element, without a for loop从 1 x n 向量创建一个 n x n-1 矩阵,其中第 i 行是没有第 i 个元素的向量,没有 for 循环
【发布时间】:2016-02-05 00:03:26
【问题描述】:

我需要这个用于拉格朗日多项式。我很好奇如果没有for 循环如何做到这一点。目前的代码如下所示:

tj = 1:n;
ti = zeros(n,n-1);
for i = 1:n
    ti(i,:) = tj([1:i-1, i+1:end]);
end

我的tj 不仅仅是一个1:n 向量,但这并不重要。虽然这个for 循环完成了工作,但我宁愿使用一些矩阵运算。我尝试寻找一些合适的矩阵来与之相乘,但到目前为止没有运气。

【问题讨论】:

    标签: performance matlab matrix vectorization matrix-multiplication


    【解决方案1】:

    这是一种方法:

    v = [10 20 30 40]; %// example vector
    n = numel(v);
    M = repmat(v(:), 1, n);
    M = M(~eye(n));
    M = reshape(M,n-1,n).';
    

    给予

    M =
        20    30    40
        10    30    40
        10    20    40
        10    20    30
    

    【讨论】:

      【解决方案2】:

      这应该推广到任何n

      ti = flipud(reshape(repmat(1:n, [n-1 1]), [n n-1]));
      

      仔细看看发生了什么。如果您仔细查看生成的矩阵,您会发现它自下而上是n-1 1、n-1 2 等。

      n 为 3 的情况。

      ti =
      
           2     3
           1     3
           1     2
      

      所以我们可以垂直翻转并得到

      f = flipud(ti);
      
           1     2
           1     3
           2     3
      

      这确实是 [1, 2, 3; 1, 2, 3] 重新整形为 3 x 2 而不是 2 x 3。

      在那个思路

      a = repmat(1:3, [2 1])
      
           1     2     3
           1     2     3
      
      b = reshape(a, [3 2]);
      
           1     2
           1     3
           2     3
      
      c = flipud(b);
      
           2     3
           1     3
           1     2
      

      我们现在又回到了您开始的地方,我们将所有内容整合在一起,将 3 替换为 n,将 2 替换为 n-1

      【讨论】:

        【解决方案3】:

        这是另一种方式。首先创建一个矩阵,其中每一行都是向量tj,但彼此堆叠。接下来,提取矩阵的下三角部分和上三角部分没有对角线,然后将结果相加,确保删除下三角矩阵的最后一列和上三角矩阵的第一列。

        n = numel(tj);
        V = repmat(tj, n, 1);
        L = tril(V,-1);
        U = triu(V,1);
        ti = L(:,1:end-1) + U(:,2:end); 
        

        numeltj 中找到我们存储在n 中的值的总数。 repmat 有助于向量 tj 的堆叠,以创建一个 n x n 大的矩阵。之后,我们使用triltriu 来提取矩阵的下三角部分和上三角部分没有对角线。此外,除相关的三角形部分外,矩阵的其余部分均为零。 triltriu-11 标志分别成功地提取了它,同时确保对角线全为零。这会在调用 tril 时创建一列额外的零,在调用 triu 时出现在第一列。最后一部分是简单地将这两个矩阵相加,忽略tril 结果的最后一列和triu 结果的第一列。

        鉴于 tj = [10 20 30 40];(借用 Luis Mendo 的示例),我们得到:

        ti =
        
            20    30    40
            10    30    40
            10    20    40
            10    20    30
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多