The Vold-Kalman Filter, introduced by Håvard Vold and Jan Leuridan in 1993, is able to extract non-stationary periodic components from a signal using a known frequency vector . Being formulated in a least-squares sense, it can be solved as a sparse linear system. Similar to the Kalman filter, VKF minimises a cost function based on a structural equation and a data equation.
This submission implements the second generation VKF with the ability to extract multiple orders at the same time, with energy spreading in case of crossing orders .
x = vkf(y,fs,f) extracts the order with frequency vector f from signal y with samplerate fs, using a 2-pole filter with a -3dB bandwidth of 1 percent of the sample rate. The output is a single waveform x.
[...] = vkf(y,fs,f,p) uses a p-order filter (typically between 1 or 4). Every order increases the roll-off by -40dB per decade. By specifying additional lower-order coefficients, zero boundary conditions are added. For instance: p = [2 0 1] applies 2nd order filtering and forces the envelope amplitude and its first derivative to zero at t_1 and t_N.
[...] = vkf(y,fs,f,p,bw) uses a bandwidth in Hertz specified by bw. If bw is a scalar, a constant bandwidth is used; if bw is a vector with the same length as y, a time-varying instantaneous bandwidth is realised.
X = vkf(y,fs,F,...) with [N,K] = size(F), performs simultaneous extraction of K orders with frequency vectors [f_1,...,f_K] in array F. In case of crossing orders, this method tries to reveal the correctorder amplitudes. The output is an array of K waveforms [x_1,...,x_K].
X = vkf(y,fs,F,p,bw,0) switches to a single-order algorithm. K orders are still extracted, but the single-order algorithm is computationally less demanding. This is suggested for high sample rates and/or long timeseries.
[a,c] = vkf(...) returns the complex envelope(s) a and phasor(s) c, such that the order waveform(s) can be reconstructed by x = real(a.*c).
[a,c,r] = vkf(...) ouputs an additional selectivity vector r used to realise the bandwidth given by bw.
Calling VKF without arguments shows a small demonstration of multi-order filtering with two crossing orders in the presence of white noise.
Note: Filter orders > 4 usually result in ill conditioning and should be avoided. The filter bandwidth determination was implemented for arbitrary order but was not verified for orders higher than 3.
Written by: Maarten van der Seijs, 2010.
Version 1.4, 3 May 2013.
 Vold, H. and Leuridan, J. (1993), High resolution order tracking at extreme slew rates, using Kalman tracking filters. Technical Report 931288, Society of Automotive Engineers.
 Tuma, J. (2005), Setting the passband width in the Vold-Kalman order tracking filter. Proceedings of the International Congress on Sound and Vibration (ICSV12), Lisbon, Portugal.
@Sean: technically it should be possible, and I agree it would make a nice addition. But I haven't planned to implement it... It would involve repeating line 149-200 for every frequency vector, so to build separate B-matrices, and a replacement of line 210 and 211 to put them on the diagonal of the larger BB matrix. A quick fix, if you ask me :-)
Very good implementation of vold kalman filtering.
I currently use this repeatably using different frequency vectors and bandwidths.
Is it possible to pass a vector with different bandwidth vectors as well as different frequency vectors? i.e. [freq_vect1, freq_vect2] and [bw_vect1, bw_vect2] ?
Thank you for your answer! I tried what you said, but the separation is a bit worse unfortunately (two linear chirps with close varying frequencies)
Anyway, it doesn't matter.
Another question, when you switch on the single-order algorithm, the computing duration is much shorter indeed, but do you know how much more efficient the multi-order algorithm is ?
Thank you !
Hi Nicolas, beating frequencies are very challenging. Perhaps what you can try is to extract them both at the same time (a second column in F), with a very narrow bandwidth setting. This way the algorithm tries to balance the energy better, because it really expects to find two signals. But I can't guarantee perfect separation...
Thank you for your job, the filter works well! I have just one question : is there a way to extract properly a signal (let's say a linear chirp) when you have another signal whose frequency is very close to the chirp's frequency ?
Dear Maarten, nice contribution indeed.
I teach experimental dynamics and created a link from my course to your code. The students will use it to analyse vehicle engine orders. Thereafter they have to manipulate the orders in order to make the car sound better (sound design).
Thank you for the comments Matthew, I made some small changes to the descriptive text. I agree with you that using the clear command within a function is not standard practice, but maybe it helps to free some memory for the sparse matrix operations that follow.
Good submission. Example works advertised, lots of helpful comment in code.
However, a few things could improve:
* why manually clear variables at the end of a MATLAB function(?)
* A demo function exists in the code but is not mentioned in the help text...
now with new m-file
Bug update for single-order algorithm.
Minor changes to description and code. Functionally the same.
Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.