我们可以使用线性索引访问矩阵,该索引遵循此模式
0 1 2
3 4 5
6 7 8
这种情况很容易得到i,j坐标(n是矩阵维度)。对于0指数,它将是。
i = index / n
j = index%n
现在,如果我的矩阵是对称的,我只想访问上半部分
0 1 2 3
.. 4 5 6
..... 7 8
........ 9
我知道线性索引将由
给出index = j + n * i - i(i-1)/ 2
但我想知道我,j给出了idx。你们知道这样做的任何方式吗?我在这里查了一下,但我找不到答案。提前谢谢。
答案 0 :(得分:8)
如果要使用您使用的索引,并且希望避免循环,则可以反转索引功能。我将使用k来表示线性索引,并且所有索引都是基于零的。正如你所说的那样
k = j + n * i - i *(i-1)/ 2。
看到我们正在使用正整数,并且所有组合(i,j)映射到不同的k意味着该函数是可逆的。我这样做的方法首先要注意
j = k - n * i + i *(i-1)/ 2
这样,如果您可以找到您所在的行,则该列由上面的等式定义。现在考虑你想要的行,它被定义为
row = min {i | k-ni + i(i-1)/ 2> = 0}。
如果求解二次方程k - ni + i(i-1)/ 2 = 0并取i的最低值,则会给出行,即
row = floor((2n + 1 - sqrt((2n + 1)^ 2 - 8k))/ 2)
然后
j = k - row * n + row *(row-1)/ 2。
在伪代码中,这将是
//Given linear index k, and n the size of nxn matrix
i = floor( ( 2*n+1 - sqrt( (2n+1)*(2n+1) - 8*k ) ) / 2 ) ;
j = k - n*i + i*(i-1)/2 ;
这消除了对循环的需要,并且对于大型矩阵来说会更快
答案 1 :(得分:4)
由于还没有人发布过Matlab解决方案,这里有一个简单的单行程序:
idxs = find(triu(true(size(A))))
给定矩阵A
,这将返回所有索引的向量,这样idxs(k)
将第k个线性索引返回到矩阵的上三角部分。
答案 2 :(得分:2)
This is comment to Keeran Brabazon answer. k = j + ni - i(i-1) /2 - this is equation from your post and it's wrong, the correct equation is k = j + (2*n -1 -i)*i/2. But we can't use it for finding i.
Equation from your post could be used to find i(row index), but we can't substitue i into your equation and get j, therefore formula for j in your post is wrong, so the final result will be looks like this:
i = floor( ( 2*n+1 - sqrt( (2n+1)*(2n+1) - 8*k ) ) / 2 ) ;(exactly like yours)
j = k - (2*n-1- i)*i/2; (different from your version, and i'm getting it by substituting i into my equation)
答案 3 :(得分:1)
循环遍历您的行,跟踪每个行的偏移量以及每个行的起始索引:
offset = 0;
startOfRow = 0;
for(i=0;i<height;i++){
endOfRow = startOfRow + (width - offset);
if(idx < endOfRow){
j = (idx - endOfRow) + width;
return {i,j};
} else {
startOfRow = endOfRow;
offset++;
}
}
我不知道Matlab,所以它只是伪代码,但它应该有效。正如霍克勒所说,确保你的索引是正确的。我在你的示例中使用了i,j
,但它只是感觉很奇怪。
答案 4 :(得分:0)
这是我能想到的最简单的方法:
int i = 1, j, x=n;
while (idx > x)
{
i++;
idx=idx-x;
x--;
}
j=idx+(i-1);
return i, j;
答案 5 :(得分:0)
基于0指数:
int j = 0;
int x = (n-1);
while (idx > x) {
j++;
idx=idx-x;
x--;
}
i=idx;
答案 6 :(得分:0)
您可以使用此
idxs = find(triu(true(size(A)))');
这是Matt答案的更新。 B,因为你想要逐行表示。
答案 7 :(得分:0)
MATLAB附带了内置函数ind2sub和sub2ind。请检查MATLAB文档。
请注意,在MATLAB中,线性索引沿行向下,索引从1开始
示例:对于3 x 3矩阵
1 4 7
2 5 8
3 6 9