使用 MATLAB 查找大向量的交集
Finding the intersection of large vectors using MATLAB
如何在 MATLAB 中比较两个信号以找到它们的交点?我的信号是可以包含重复值的大向量。
我一直在使用 intersect
试验以下方法,它适用于随机生成的信号。
% Example case
sig1 = rand(100,1);
sig2 = [sig1(end-10:end); rand(90,1)]; % a signal with imposed intersection.
[c, ia, ib] = intersect(sig1, sig2);
plot(sig2)
hold on
scatter(ib, sig2(ib), 'filled')
hold off
我正在对我的真实数据使用这种方法,但它没有产生正确的交集,这是由于信号中的重复值。因此,我想为两个信号添加一个非常小的随机噪声,然后应用 intersect
,但是,添加阈值对于 intersect
.
是不可能的
有人能给我一些提示,说明如何稳健有效地找到两个大信号测量的交点吗?还有其他方法吗?提前谢谢你。
背景:
其实我有几个大的录音,sig1
,sig2
,sig3
,......每两个连续的录音,例如sig1
和sig2
可能有重叠,这意味着 sig1
的录音结尾可能与 sig2
的开头完全相同。所以,我的目标是检查是否有任何重叠,检测它们,然后删除它们以便能够连接所有测量值:sig1
、sig2
、sig3
、...
我也知道这些录音的顺序,所以交集可以认为是sig1(end-N:end) = sig2(1:N+1)
。
这方面的典型方法是互相关 (the signal processing toolbox has the function xcorr
)。互相关的峰值表示两个信号最相似的延迟。这就是您需要找出两个信号重叠多少的全部内容。
因为您想将一个信号的尾部与另一个信号的头部进行比较,我们将仅对信号的那些部分应用互相关。这确实需要知道重叠可以有多大(某个上限),这是不理想的。如果我们计算互相关的裁剪部分太短(即不包含完全重叠),则计算的偏移将不正确。如果时间太长,互相关可能无法识别正确的偏移(峰值可能隐藏在噪声中)。也许其他人可以采用这个想法并从中构建更强大的东西...
(我没有安装信号处理工具箱,所以我使用 fft
和 ifft
来实现它)
% Two example signals
sig1 = rand(100,1);
sig2 = [sig1(end-10:end); rand(90,1)];
% Take the end of sig1 and the start of sig2
N = 15; % should be larger than the overlap
end1 = sig1(end-N+1:end);
start2 = sig2(1:N);
% Compute cross-correlation
xc = ifft(fft(end1).*conj(fft(start2)));
% Find peak
[~,shift] = max(xc);
% Crop signal #2
Nrep = N-shift+1
sig2_cropped = sig2(Nrep+1:end);
% Plot
clf
subplot(2,1,1)
plot(sig1)
hold on
plot(numel(sig1)-Nrep+1:numel(sig1),sig1(end-Nrep+1:end),'r.')
subplot(2,1,2)
plot(sig2)
hold on
plot(1:Nrep,sig2(1:Nrep),'r.')
一个可能更健壮但比上面的更慢的快速和肮脏的替代方法是在循环中实现比较:
Nrep = 0;
for N = 1:min(numel(sig2),numel(sig1))
% Take the end of sig1 and the start of sig2
end1 = sig1(end-N+1:end);
start2 = sig2(1:N);
% Compare
if all(end1==start2) % possibly do this with a tolerance
Nrep = N;
break
end
end
这里我们开始与 1 个样本的重叠进行比较,然后将其逐一增加,直到找到匹配项。如果未找到匹配项,Nrep==0
,则不会重复任何样本。
使用 ismember
或者可能 ismembertol
如果你想要一个公差。
sig1 = rand(100,1);
sig2 = [rand(50,1); sig1(end-10:end); rand(50,1)]; % a signal with imposed intersection.
idx = ismember(sig1,sig2); %multiple occurences variant of IA in [C,IA,IB]=intersect(sig1,sig2)
inter = sig1(idx) %The intersection
如何在 MATLAB 中比较两个信号以找到它们的交点?我的信号是可以包含重复值的大向量。
我一直在使用 intersect
试验以下方法,它适用于随机生成的信号。
% Example case
sig1 = rand(100,1);
sig2 = [sig1(end-10:end); rand(90,1)]; % a signal with imposed intersection.
[c, ia, ib] = intersect(sig1, sig2);
plot(sig2)
hold on
scatter(ib, sig2(ib), 'filled')
hold off
我正在对我的真实数据使用这种方法,但它没有产生正确的交集,这是由于信号中的重复值。因此,我想为两个信号添加一个非常小的随机噪声,然后应用 intersect
,但是,添加阈值对于 intersect
.
有人能给我一些提示,说明如何稳健有效地找到两个大信号测量的交点吗?还有其他方法吗?提前谢谢你。
背景:
其实我有几个大的录音,sig1
,sig2
,sig3
,......每两个连续的录音,例如sig1
和sig2
可能有重叠,这意味着 sig1
的录音结尾可能与 sig2
的开头完全相同。所以,我的目标是检查是否有任何重叠,检测它们,然后删除它们以便能够连接所有测量值:sig1
、sig2
、sig3
、...
我也知道这些录音的顺序,所以交集可以认为是sig1(end-N:end) = sig2(1:N+1)
。
这方面的典型方法是互相关 (the signal processing toolbox has the function xcorr
)。互相关的峰值表示两个信号最相似的延迟。这就是您需要找出两个信号重叠多少的全部内容。
因为您想将一个信号的尾部与另一个信号的头部进行比较,我们将仅对信号的那些部分应用互相关。这确实需要知道重叠可以有多大(某个上限),这是不理想的。如果我们计算互相关的裁剪部分太短(即不包含完全重叠),则计算的偏移将不正确。如果时间太长,互相关可能无法识别正确的偏移(峰值可能隐藏在噪声中)。也许其他人可以采用这个想法并从中构建更强大的东西...
(我没有安装信号处理工具箱,所以我使用 fft
和 ifft
来实现它)
% Two example signals
sig1 = rand(100,1);
sig2 = [sig1(end-10:end); rand(90,1)];
% Take the end of sig1 and the start of sig2
N = 15; % should be larger than the overlap
end1 = sig1(end-N+1:end);
start2 = sig2(1:N);
% Compute cross-correlation
xc = ifft(fft(end1).*conj(fft(start2)));
% Find peak
[~,shift] = max(xc);
% Crop signal #2
Nrep = N-shift+1
sig2_cropped = sig2(Nrep+1:end);
% Plot
clf
subplot(2,1,1)
plot(sig1)
hold on
plot(numel(sig1)-Nrep+1:numel(sig1),sig1(end-Nrep+1:end),'r.')
subplot(2,1,2)
plot(sig2)
hold on
plot(1:Nrep,sig2(1:Nrep),'r.')
一个可能更健壮但比上面的更慢的快速和肮脏的替代方法是在循环中实现比较:
Nrep = 0;
for N = 1:min(numel(sig2),numel(sig1))
% Take the end of sig1 and the start of sig2
end1 = sig1(end-N+1:end);
start2 = sig2(1:N);
% Compare
if all(end1==start2) % possibly do this with a tolerance
Nrep = N;
break
end
end
这里我们开始与 1 个样本的重叠进行比较,然后将其逐一增加,直到找到匹配项。如果未找到匹配项,Nrep==0
,则不会重复任何样本。
使用 ismember
或者可能 ismembertol
如果你想要一个公差。
sig1 = rand(100,1);
sig2 = [rand(50,1); sig1(end-10:end); rand(50,1)]; % a signal with imposed intersection.
idx = ismember(sig1,sig2); %multiple occurences variant of IA in [C,IA,IB]=intersect(sig1,sig2)
inter = sig1(idx) %The intersection