# Matlab - Bode plot of Lag Filter + Integrator

I am rather new to Matlab and I just cant make sense of what I see in the bode plot of the continuous and discrete version of the same function. The bode plot of the continuous function looks as expected. However the bode plot of the discrete version has a phase offset of +90 degrees and the gain stays the same at lower frequencies. It's basically a lag compensator with an integrator. This is not the final result I am going for, but the easiest example I could think of to make the problem as clear as possible. Please note that I am using a rather high sampling rate of ~12 MHz, which is what I need in the final hardware design. The high sampling rate seems to be part of the problem. With lower sampling rates the frequency at which the bode plots differ gets shifted to the left.

Can anyone explain this behaviour and maybe how I can achieve a result that is closer to the continuous bode plot using the high sampling rate?

Code of the example:

FS = 48000*256;
T_sample = 1/FS;

accu = tf([0 1], [1 0]);
lag = tf([10 1], [100 1]);

lag_d = c2d(lag, T_sample, "zoh");
accu_d = c2d(accu, T_sample, "zoh");

bode(lag*accu, lag_d*accu_d);

• Your running into some computer resolution problem with octave (and probably in Matlab); with the lead-lag network. It almost works with lag = tf([.1 1], [1 1]); and does work with lag = tf([.01 1], [.1 1]). If you don't want to change this then do the system conversion by hand. I have no idea where the internals are going wrong. i.e. skip the c2d. – rrogers Oct 15 '19 at 21:08
• I did add pkg load control format long to my program and generated two separate graphs; trouble-shooting. Do you want me to plunk around and post more detailed, i.e. hand conversion, results. – rrogers Oct 15 '19 at 21:46
• Thanks for the answer. Sry, for the late answer, but i didnt see ur comment on until just now. Well, even with lag = tf([.01 1], [.1 1]) i see the gain and phase offset at around 10^-3 rad/s. So basically this only shifts the problem around. I am not sure if a manual conversion would make a big difference and I cant really image that Mathworks did this wrong in any way. So the question is: is what we see correct or is it a problem that can only be seen in the graph. The other thing is: the dcgain of the continous function is +inf. The discrete dcgain is limited which is what i would expect. – Martin Oct 18 '19 at 13:26

I tried it in Octave, there's definitely a glitch like you said. I tried it with "Tustin" instead of "zoh", same result.

However I was puzzled by your high sampling frequency. Your lag controller has a pole at s = -0.01 and a zero at s = -0.1, they are both "slow" while your sampling frequency is really high.

How to fix it : Change your sampling frequency to something much lower than 12 MHz, like 10 kHz for instance and replace "zoh" by "tustin". "Zoh" should only be used when converting a "process" transfer function to the discrete domain in order to take in account the effect of the DAC, we don't use it for compensators.

The root cause however is probably some quantization issue in the c2d function.

FS = 10e3;
T_sample = 1/FS;

accu = tf([0 1], [1 0]);
lag = tf([10 1], [100 1]);

accu_d = c2d(accu, T_sample, "tustin");
lag_d = c2d(lag, T_sample, "tustin");

figure
bode(lag*accu, accu_d*lag_d);


Edit 1 :

The issue seems to be with the lag controller, not the accumulator. You should try to move the pole and the zero to the left, this should fix your problem since you must keep your sampling frequency really high:

try this (same DC gain, but pole and zero further to the left) :

lag = tf([1 1000], [10 1000]);

• Thank you very much for the answer. Unfortunately, I cant set the sampling frequency lower than this, cuz I am developing a digital hardware PLL which runs at this frequency and I would like the matlab model to be as accurate as possible concerning settling time and so on. I also tried Octave before that and it does provide even weirder results (spikes in the lower frequency band). Nevertheless, I assume I am just misunderstanding something, and this effect is probably "normal" but I would really like to understand the math behind this phase shift. – Martin Oct 14 '19 at 13:04
• Btw the lag controller is just a dummy here. Not representing the values I would normally use, but to illustrate the issue more easily. – Martin Oct 14 '19 at 13:05

You should see that figure(2) is the only process that avoids some errors. Note on figure (1) the magnitude overlaps; you can add a constant say
bode(lag_daccu_d,lagaccu+.0001,pts);
to split them bu that messes up the phase plot.
I didn't track down where the errors were coming from but note that octave says it uses the same code base for this as Matlab; SLICOT.

## Octave code

format long;

FS = 48000*256;
T_sample = 1/FS;

accu = tf([0 1], [1 0]);
lag = tf([10 1], [100 1]);

lag_d = c2d(lag, T_sample, "zoh");
accu_d = c2d(accu, T_sample, "zoh");
sys_d = c2d(lag*accu, T_sample, "zoh");

pts = linspace(.001,1000000,10000);
figure(1);
bode(lag_d * accu_d , lag * accu,pts);
figure(2);
bode(sys_d,pts);
figure(3); bode(sys_d);

• Thanks for the reply. Unfortunately figure 2 does not avoid the problem, since the comparison graph is the continuous graph, which does differ by quiet a lot in the lower frequency range. Octave does NOT use the same code base as Matlab btw. It produces quiet different results. – Martin Oct 22 '19 at 11:54