ind2sub用于三角矩阵的非零元素

时间:2016-10-24 05:17:29

标签: matlab matrix indexing

我只想简单地找到(row,col)的索引,它是矩阵A的最小点。我可以使用

[minval, imin] = min( A(:) )

和MATLAB内置函数

[irow, icol] = ind2sub(imin);

但是出于效率原因,矩阵A是三角形的,我想实现以下函数

function [i1, i2] = myind2ind(ii, N);

k = 1;
for i = 1:N
    for j = i+1:N
        I(k, 1) = i;    I(k, 2) = j;
        k = k + 1;
    end
end
i1 = I(ii, 1);
i2 = I(ii, 2);

此函数为以下输入返回8和31

[irow, icol] = myind2ind(212, 31);  % irow=8, icol = 31

如何在不使用内部" I"?

的情况下更有效地实现myind2ind功能

1 个答案:

答案 0 :(得分:0)

I矩阵可以由nchoosek生成。

如果是N = 5那么我们有

N =5
I= nchoosek(1:N,2)
ans =

   1   2
   1   3
   1   4
   1   5
   2   3
   2   4
   2   5
   3   4
   3   5
   4   5

4 repeated 1 times
3 repeated 2 times
2 repeated 3 times
1 repeated 4 times

因此我们可以使用Gauss formula for triangular number

获取I的行数
(N-1) * (N-1+1) /2 =
N * (N -1) / 2 =
10

jj = size(I,1) + 1 - ii作为行索引I,从我的结尾开始并使用N * (N -1) / 2,我们可以制定quadratic equation

N * (N -1) / 2 = jj
(N^2 -N)/2 =jj

所以

N^2 -N - 2*jj = 0

它的根源是:

r = (1+sqrt(8*jj))/2

r可以舍入并从N中减去,以获得所需输出的第一个元素(三角矩阵的行数)。

R = N + 1 -floor(r);

对于列号,我们找到当前行idx_first的第一个元素R的索引:

idx_first=(floor(r+1) .* floor(r)) /2;

然后通过从当前行的第一个元素的线性索引中减去当前线性索引并向其添加R来找到列号。

这是实现的功能:

function [R , C] = myind2ind(ii, N)
    jj = N * (N - 1) / 2 + 1  - ii;
    r = (1 + sqrt(8 * jj)) / 2;
    R = N  -floor(r);
    idx_first = (floor(r + 1) .* floor(r)) / 2;
    C = idx_first-jj + R + 1;
end