Fast implementation of calculating peaks/local maxima of magnitude of transfer function
13 views (last 30 days)
Show older comments
Hi,
I need to calculate different peak values of the magnitude of the transfer function. The peaks are all local maxima, not just the highest value. I have the code below to illustrate an example. You could see that the values in pks_vect_maxima are matching with the values in Bode plot. This is my current implementation and it is slow for my application. I think going through Bode route makes it slow. Is there a better/faster way for implementation? I am looking for a solution that works for general cases of transfer function order.
Thanks,
clear all;
options_bode = bodeoptions;
options_bode.MagUnits = 'abs';
G_tf = tf([0.2461, -0.0829, -0.0673, 0.0829, -0.1788], ...
[1.0000, -1.2841, 1.0272, -0.9329, 0.5279],1);
figure;
hold on;
bodemag(G_tf,'g',options_bode)
% Calculate local maxima/peaks value of transfer function
[mag,phase,wout] = bode(G_tf);
mag_vect = mag(:);
[pks_vect_maxima,locs_maxima] = findpeaks(mag_vect);
0 Comments
Answers (1)
Star Strider
on 17 Nov 2018
Using the Signal Processing Toolbox function is significantly faster:
b = [0.2461, -0.0829, -0.0673, 0.0829, -0.1788];
a = [1.0000, -1.2841, 1.0272, -0.9329, 0.5279];
figure
[h,w] = freqz(b, a, 2^14);
[pks_vect_maxima2,locs_maxima3] = findpeaks(abs(h));
with the bode and findpeaks calls requiring about 1.7 seconds and the freqz and findpeaks calls requiring about 0.05 seconds when I tested them
You need to decide if the extrra coding required is worth the effort.
My test code:
options_bode = bodeoptions;
options_bode.MagUnits = 'abs';
G_filt_discrete = tf([0.2461, -0.0829, -0.0673, 0.0829, -0.1788], ...
[1.0000, -1.2841, 1.0272, -0.9329, 0.5279],1);
t1 = clock;
figure;
hold on;
bodemag(G_filt_discrete,'g',options_bode)
% Calculate local maxima/peaks value of transfer function
[mag,phase,wout] = bode(G_filt_discrete);
mag_vect = mag(:);
[pks_vect_maxima,locs_maxima] = findpeaks(mag_vect);
t2 = clock;
pkw = wout(locs_maxima)
b = [0.2461, -0.0829, -0.0673, 0.0829, -0.1788];
a = [1.0000, -1.2841, 1.0272, -0.9329, 0.5279];
figure
[h,w] = freqz(b, a, 2^14);
[pks_vect_maxima2,locs_maxima2] = findpeaks(abs(h));
t3 = clock
pkw2 = w(locs_maxima2)
et1 = etime(t2,t1)
et2 = etime(t3,t2)
3 Comments
Star Strider
on 17 Nov 2018
That is the only alternative I can suggest. You can experiment with decreasing the fft lengths (from 2^14 to 2^10 or something shorter). I doubt there any faster possibilities.
The tradeoff is speed or precision in calculating the function from which to derive the peak amplitudes and locations. Longer fft vectors are more precise (providing increased frequency resolution), and are by definition slower. It depends on what you want.
I will delete my Answer in a few hours, since it did not turn out to be helpful.
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!