用另一个向量逼近向量的值

时间:2013-11-07 20:02:59

标签: matlab

我需要将第一列中的值近似到第二列中最接近的值(我知道需要一个阈值,它可能是0.0090)并保存索引。 我使用以下内容:

[ms, ix] = sort(m(:));
[r, c] = ind2sub(size(m),ix); 
proximity_threshold = 0.0090; 
ind = (diff(ms)<proximity_threshold);  
ind(end+1)=0;
n=0;
nn=0;
while n<numel(ix) 
    n=n+1;
    nn=nn+1;
    if ind(n) & c(n)~=c(n+1)
        a(nn,c(n))=ms(n);
        a(nn,c(n+1))=ms(n+1);
        n=n+1;
    else
        a(nn,c(n))=ms(n);
    end
end

但我对此实施不满意。它近似值,但它返回一个大小(900 x 2)的矩阵,我想要一个与原始矩阵相同的矩阵(500x2)。

谢谢!

2 个答案:

答案 0 :(得分:3)

首先,您可以跳过矩阵m。在这种情况下,这是一个不太理想的解决问题的方法。另外,摆脱x_t末尾的零点。它们不是必需的。如果您需要帮助修剪零结束,请尝试:

x_t = x_t(1:find(x_t~=0,1,'last'));

现在,为了匹配。您可以使用以下内容在x_t中找到与x元素最接近的匹配项:

B = bsxfun(@minus, x_t(:), x(:).'); %'
[idx,~] = find(bsxfun(@eq, abs(B), min(abs(B))));
y = x_t(idx);

现在x中可以找到y的近似值,并在idx中找到相应的索引。

解释


bsxfun(@minus, x, y);

这将采用列向量x并通过行向量y的每个元素或每个元素减去它。例如,

>> x = [3 6 9 12].'; y = [1 2 3];
>> ans = bsxfun(@minus, x, y);

ans =

     2     1     0
     5     4     3
     8     7     6
    11    10     9

或换句话说,正在发生的事情是:

ans =

 (3-1)   (3-2)   (3-3)
 (6-1)   (6-2)   (6-3)
 (9-1)   (9-2)   (9-3)
(12-1)  (12-2)  (12-3)

bsxfun(@eq, A, min(A));

这将在列最小值所在的矩阵A的列中查找位置。它返回一个逻辑矩阵(1和0)。例如,

>> A = [ 1  2  3  4;
      3  3  6  5;
      2  2  0  7;
      5  1  8  5;
      4  5  2  6];

>> ans = bsxfun(@eq, A, min(A))

ans =

    1   0   0   1
    0   0   0   0
    0   0   1   0
    0   1   0   0
    0   0   0   0

[idx,~] = find(A);

find命令搜索矩阵A的所有非零元素。通常你会把它称为[row, col] = find(A);来取回行和列,但由于我只对行感兴趣,我使用~告诉Matlab我不想保留列值


y = x(idx);

这会创建一个新的向量y,其中包含x引用的idx元素。由于我已经找到了最小化错误的索引,因此我使用它们来获取这些索引处的x值。


全部放在一起:

在较高级别,代码执行以下操作:

  • 矩阵Bx(列)的每个值与x_t(行)的每个值进行比较
  • 对于x的每一列(B),找到最小化错误的行(x_t)。
  • 知道行,我们可以使用行索引直接提取x_t值。

    希望这有帮助!

    更新

    我意识到,如果x的值与x_t的两个值之间的距离完全相同,那么您最终会得到一个太长的向量,因为会选择多个答案。以下是问题的解决方法。

    B = bsxfun(@minus, x_t(:), x(:).'); %'
    [idx,col] = find(bsxfun(@eq, abs(B), min(abs(B))));
    idx(1 < sum(triu(bsxfun(@eq, col(:), col(:).')))) = []; %'
    y = x_t(idx);
    

    基本上,添加的行会丢弃与给定列中第一个匹配项不对应的任何索引值。

  • 答案 1 :(得分:2)

    nispio的答案很好,但匹配比必要复杂得多。 interp1函数可用于将值映射到查找表条目。

    根据nispio的方法修剪x_t:

    x_t = x_t(1:find(x_t~=0,1,'last'));
    

    现在我们使用专为表查找设计的功能。

    idx = interp1(x, 1:numel(x), x_t, 'nearest');
    

    最后,获取找到的值,与nispio相同:

    y = x(idx);