从 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
以便我们提取矩阵的下三角部分和上三角部分 而没有 对角线。此外,矩阵的其余部分除了相关的三角形部分外全部为零。 tril
和 triu
的 -1
和 1
标志分别成功提取出来,同时确保对角线全为零。这会创建一列额外的零,调用 tril
时出现在最后一列,调用 triu
时出现在第一列。最后一部分是简单地将这两个矩阵相加,忽略 tril
结果的最后一列和 triu
结果的第一列。
鉴于 tj = [10 20 30 40];
(借用 Luis Mendo 的例子),我们得到:
ti =
20 30 40
10 30 40
10 20 40
10 20 30
拉格朗日多项式需要这个。我很好奇在没有 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
以便我们提取矩阵的下三角部分和上三角部分 而没有 对角线。此外,矩阵的其余部分除了相关的三角形部分外全部为零。 tril
和 triu
的 -1
和 1
标志分别成功提取出来,同时确保对角线全为零。这会创建一列额外的零,调用 tril
时出现在最后一列,调用 triu
时出现在第一列。最后一部分是简单地将这两个矩阵相加,忽略 tril
结果的最后一列和 triu
结果的第一列。
鉴于 tj = [10 20 30 40];
(借用 Luis Mendo 的例子),我们得到:
ti =
20 30 40
10 30 40
10 20 40
10 20 30