I'm using the Signal Processing Toolbox in MATLAB to design a Butterworth low-pass filter. I'm told that my filter has been giving some unexpected results. In particular, when the values from this filter are differentiated (i.e. to calculate velocity from a position signal), the velocity values are coming out a little too high. However, with my limited experience in the field of Signal Processing, it's not clear exactly how the filter is failing, or indeed whether there is fact a problem at all. Perhaps the filter is somehow artificially raising the absolute value of the signal? Below is a MWE of the code I have written, based on the Signal Processing Toolbox, commented to try to explain each step. My question is: is this a simple case of a (correctly-implemented) low-pass filter or is there a better solution I might try? Note that my (true) input data tend to have NaNs throughout; hence I include here some code to interpolate those before feeding into the filter.

function filteredData = testfilter(inputData)

%% Generate an example signal
inputData = filter([1,1],1,randn(1000,1));

%% Set filter parameters
dataSamplingRate_hz = 1000;
order = 4;
cutoff = 90;

%% Apply filter
nyquistFrequency = dataSamplingRate_hz/2; % find the Nyquist frequency
filterCutoff = cutoff/nyquistFrequency;

[b,a] = butter(order,filterCutoff); % define the filter

%[b,a] = besself(order,cutoff/nyquistFrequency); % maybe a Bessel filter would be better to use instead???
filteredData = nan(size(inputData)); % preallocate resources
for i = 1:size(inputData,2) % for each column of inputData
    timestampsOfNans = isnan(inputData(:,i)); % find the timestamps of NaNs
    inputDataInterpolated = interpolatenans(inputData(:,i)); % replace NaNs with interpolated data (filters can't handle NaNs)
    filteredData(:,i) = filtfilt(b,a,double(inputDataInterpolated)); % filter the data (n.b. filtfilt() requires doubles)
    filteredData(timestampsOfNans,i) = NaN; % replace the NaNs back into the vector

%% Plot the 'before and after' signal
hold on

function data = interpolatenans(data)
% Interpolates NaNs in a vector by approximating with the data either side of the gap

nans = isnan(data); % find nans
t = 1:length(data);
data(nans) = interp1(t(~nans),data(~nans),t(nans),'linear');

The above code produces the following plot, which looks - to my untrained eye - to be appropriate. Is this the case?

enter image description here

(I recognise that at this stage, I do not have a specific problem to address here, as I do not yet understand why my code is producing elevated values. If a specific problem is found with this code, I will adjust my question to reflect the underlying issue)

  • $\begingroup$ Can you show/describe what you consider to be elevated values? This is (at least to me) not directly apparent from the plots ... $\endgroup$ – user883521 Sep 7 '17 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.