根据向量创建逐行增加差异的矩阵

时间:2015-02-16 12:59:45

标签: matlab loops matrix

我在MATLAB中有一个列向量,我正在尝试构建一个差异矩阵,其中行差异大小不同。

很难用语言解释,所以我将举例说明:

我想说的数据是:

data = [ 1 2 3 4 5 6 ];

我想要做的是制作一个矩阵,这样就可以得到差异(每个列的差异大小会改变[增加一个]):

diff = 
[(2 - 1) ...
 (3 - 2) (3 - 1) ...
 (4 - 3) (4 - 2) (4 - 1) ...
 (5 - 4) (5 - 3) (5 - 2) (5 - 1) ...
 (6 - 5) (6 - 4) (6 - 3) (6- 2) (6 - 1)]

我最好的猜测是做一个带嵌套循环的三角矩阵。我的MATLAB代码如下所示:

differences = zeros(length(data) - 1, length(data) - 1);
step = 0;  

for j = 1:1:size(data) - 1; 
    for i = 1:size(logquarterly) - 1 - step;

        if j <= i;
        differences(i,j) = data(i + 1 + step , 1) - data(i,1);
        step = step + 1;
        end

    end
end

我要做的是计算距离为1的第一列差异,然后计算距离为2的第二列差异等等......为了适应我需要的必要行值,我使用的是“步骤“为计算第一列而设置为零的变量,然后我希望它在计算第二列时具有正确的尺寸时增加1。但我不能让它发挥作用。如果我采取“步骤”并使用它:

differences = zeros(length(data) - 1, length(data) - 1);


for j = 1:1:size(data) - 1; 
    for i = 1:size(logquarterly) - 1;

        if j <= i;
        differences(i,j) = data(i + 1 , 1) - data(i,1);
        end

    end
end

一切正常,但每个列的差异距离相同,并且不会增加一个。任何想法的家伙?

2 个答案:

答案 0 :(得分:4)

如果我理解正确,你想这样做:

data = [ 1 2 3 4 5 6 ];
n = numel(data);

%// calculate differences
diffs = bsxfun(@minus, data(end:-1:1), data(end:-1:1).')  

%'
%// get linear indices from circulant sub-indices for rows and 
%// linear indices for columns
idx = sub2ind([n n], gallery('circul',n:-1:1), ndgrid(1:n,1:n))

%// mask output and get lower triangular matrix
output = tril(diffs(idx(n-1:-1:1,n-1:-1:1)))

所以输出是:

output =

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

答案 1 :(得分:1)

您的解决方案的问题在于它仅适用于列向量,因为循环j = 1:1:size(data)-1size的来电将返回[1,6];然后应用-1,产生[0,5]。然后只取这个向量的第一个值,而for循环只会从1运行到1-1==0,即NOT。 请改用numelsize(.,1) / size(.,2)。 (循环初始化后也不要使用semicola ;)。 (试试MATLAB调试器!)

以下是我对如何修复方法的看法:

differences = zeros(length(data)-1, length(data)-1);
for j = 1:size(differences,2) 
    for i = j:size(differences,1)
        differences(i,j) = data(i+1) - data(i-j+1);
    end
end

我喜欢使用gallery('circul',n:-1:1),在 thewaywewalk 的答案中,我确实发现其余部分有点过于复杂。

这是我重复使用他的想法:

n = numel(data);
L = ndgrid(2:n,2:n);           % // Generate indices for Left side of operator
R = gallery('circul',1:n-1).'; %'// Generate indices for Right side of operator
out = tril(data(L) - data(R))  % // Do subtraction of corresponding indices
相关问题