【问题标题】:Create matrix of row-wise increasing differences based on vector基于向量创建逐行递增差异矩阵
【发布时间】:2015-04-16 23:54:25
【问题描述】:

我在 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 的第二列差异,依此类推...为了适应我需要的必要行值,我使用“ step”变量,它设置为零用于计算第一列,然后我希望它在计算第 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

一切正常,但每一列的差异距离相同,并且不会增加一。有什么想法吗?

【问题讨论】:

  • logquarterly 到底是什么?为什么不写下给定样本输入的最终预期值?如果预期的输出是一个二维数组,并且似乎会有空格,那么这些空格的填充符应该是什么?也许使用随机的东西而不是 1,2,3,4,5,6 作为输入元素?

标签: matlab loops matrix


【解决方案1】:

您的解决方案的问题在于,它仅适用于列向量,因为循环 j = 1:1:size(data)-1size 的调用将返回[1,6];然后应用 -1 产生[0,5]。然后只取这个向量的第一个值,然后 for 循环只会从1 运行到1-1==0,即不是。 请改用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

我喜欢在 thewaywewalk 的回答中使用gallery('circul',n:-1:1),但我确实觉得其余部分太复杂了。

这是我重用他的想法的看法:

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

【讨论】:

  • 你太棒了!谢谢。
  • 我有点想多了,对于非常大的数组(n > 5000),你的方法也快一点。我的赞成票你已经有;)
  • @thewaywewalk:我真的很喜欢使用gallery('circul'),因为我从未见过它,所以我只是不得不自己尝试一下。 :-)
  • @knedlsepp 画廊功能提供了许多其他可能性。不幸的是,文档真的很糟糕,除非你知道所有测试函数的数学背景,否则很难浏览和使用它们。
  • @thewaywewalk:我看了一眼doc gallery后的想法。
【解决方案2】:

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

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

【讨论】:

  • 这不适合我。你确定你的最后一个命令是flip 吗?不应该是flipud还是fliplr
  • @kkuilla flip 可能在旧版本的 matlab 中不可用,看看我的编辑
  • gallery 的绝招我不知道这个功能 +1
猜你喜欢
  • 2014-03-19
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 2016-01-16
  • 2010-11-03
  • 2022-12-03
  • 2015-03-26
相关资源
最近更新 更多