I am trying to find the time shift between two vectors.
My function succeeds on randomly generated vectors, but fails on small shifted, high sampling rate vectors.
class MapperDumpsValidator(object): @staticmethod def cross_correlation_shift_from_overlapping_position(static, moving): from scipy.signal import correlate correlation = correlate(static, moving, mode='full') shift = np.argmax(correlation) return shift, correlation @staticmethod def pad_and_shift_moving_to_static(static, moving): static /= np.linalg.norm(static) moving /= np.linalg.norm(moving) shift, correlation = MapperDumpsValidator.cross_correlation_shift_from_overlapping_position(static, moving) # shift -=1 augmented_shift = shift - (len(moving) - 1) augmented_static = static[augmented_shift: augmented_shift + len(moving)] moved = moving diff = augmented_static - moved plt.figure() plt.plot(static[augmented_shift: augmented_shift + len(moving)]) plt.plot(moving) plt.plot(diff) plt.show() assert np.count_nonzero(diff) == 0 return diff
And the test:
def correlate_missing_signal(v): start = 100 end = len(v)-start reference = v moving = v[start:end] diff = MapperDumpsValidator.pad_and_shift_moving_to_static(reference, moving) plt.figure() plt.plot(diff) plt.show()
v = np.random.rand(10000, 1) correlate_missing_signal(v)
This passes the assertion, and the diff is zero as expected (same input vector, augmented by size).
When I pass in a vector which was samples at high rate, and is shifted by 1, the output
augmented_shift is 0, instead of 1.
This is probably due to very small contributions by every single element, which are all smaller than the single contribution of the leftmost and rightmost elements, which are not present if the shift is 1, and are present if the shift is 0.
- Did I use the correlation correctly?
- If so, How can I get the correct result for vectors of high sampling rate, and small shift?
graphs for illustration of input: