从 1 x n 向量创建一个 n x n-1 矩阵,其中第 i 行是没有第 i 个元素的向量,没有 for 循环

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

拉格朗日多项式需要这个。我很好奇在没有 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 循环可以完成工作,但我宁愿使用一些矩阵运算。我试着寻找一些合适的矩阵来乘以它,但到目前为止运气不好。

这应该推广到任何 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 时,我们现在回到了您开始的地方。

这里有一个方法:

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

这是另一种方法。首先创建一个矩阵,其中每一行都是向量 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); 

numel finds the total number of values in tj which we store in n. repmat facilitates the stacking of the vector tj to create a matrix that is n x n large. After, we use tril and triu 以便我们提取矩阵的下三角部分和上三角部分 而没有 对角线。此外,矩阵的其余部分除了相关的三角形部分外全部为零。 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