Matlab中两个向量之间的值的相互作用

时间:2011-03-29 13:54:34

标签: matlab vector

我有两个长度相等的向量oc

o = [-1 -1 -1  0 0 0 1 1 0  0];
c = [-1 -1 -1 -1 0 1 1 1 0 -1];

o表示打开信号(neg或pos),c表示关闭信号,假设开启信号在其前面有相反的符号。一次只能激活一个信号,因此必须忽略连续信号。在上面的两个向量中,我的第一个信号将在o(1)中,其相应的结束信号将在c(6)中找到。这也意味着o(2)o(3)中的开启信号应该被忽略,我的下一个开启信号位于o(7),其相应的关闭位于c(10),从而导致o(8)

处的无效信号

我正在尝试找到一个矢量化解决方案来识别正确的序列或打开/关闭信号的索引,以产生以下解决方案示例的内容:

o = [-1 0 0 0 0 0 1 0 0  0];
c = [ 0 0 0 0 0 1 0 0 0 -1];

我显然可以通过循环遍历for循环中的每个元素来解决这个问题,但由于我的数据集可以达到数百万个元素,而且我发现Matlab中的循环可能相当“昂贵”,如果有人有解决方案我会非常感激我的问题是面向矩阵的,还是通过arrayfun或类似的东西来提高代码的效率?

2 个答案:

答案 0 :(得分:1)

您可以使用diff以及一些逻辑操作来获得答案。

o=[-1,-1,-1,0,0,0,1,1,0,0];
oFinal=abs(diff([0,o])).*o;

oFinal=

    -1     0     0     0     0     0     1     0     0     0

诀窍是diff和原始向量o的输出在o中仅在第一次出现的值时在同一索引处具有非零值(即,首次出现在链中)。因此,通过将元素与o相乘,您就得到了答案。 abs是为了确保由于diff的输出而未发生符号更改。

c的方法类似,我会留下让你尝试:)

答案 1 :(得分:0)

通常循环并不像执行一些其他操作那样昂贵,这些操作只是隐藏了另一个函数(例如arrayfun)后面的循环。从你的文字中可以看出你刚刚选择了错误的算法。你的问题听起来很线性,那就是O(n),但你写的是关于循环的循环,这意味着O(n ^ 2)。拥有数百万个元素的二次运行时并不是那么好。

您想要的算法是这样的:

open = 0;

for i=1:length(o)
  if (open == 0) 
     open=o(i)
  else 
     o(i) = 0;
  end
  if (c(i) ~= -open) 
     c(i) = 0;
  else 
     open = 0;
  end
end

它可能需要一些微调,因为你没有详细描述,例如c和o信号的顺序是什么(例如,如果相同的索引打开和关闭,首先是打开处理或关闭,我的示例代码假定打开),或者信号的顺序是否总是正常,或者是否必须是一些错误处理 - 但我猜你得到了单循环的想法。