# minreal tolerance not respected

8 views (last 30 days)
Daniel Magree on 18 Nov 2022
Commented: Paul on 28 Nov 2022
minreal documentation says that it does a simple pole-zero comparsion for cancelation. However, simple examples seem to behave differently. Even the example in the Pole-Zero simplification document fails to behave as described:
G = zpk(3e-8,[-1,-3],1);
C = pid(1,0.3);
T = feedback(G*C,1)
T = (s+0.3) (s-3e-08) ---------------------- s (s+4.218) (s+0.7824) Continuous-time zero/pole/gain model.
% compute minreal with a tolerance that ought to cancel
Tred = minreal(T, 1e-7)
Tred = (s+0.3) (s-3e-08) ---------------------- s (s+4.218) (s+0.7824) Continuous-time zero/pole/gain model.
As you can see, the zero at 3e-8 and 0 do not cancel, even though they are less than 1e-7 away. It eventually cancels at tolerance of 1e-3. It appears that the elimination criteria is the the square of the distance, rather than the distance, but that is not at all clear from the documentation or the example above.

Paul on 19 Nov 2022
Edited: Paul on 19 Nov 2022
Hi Daniel,
As best I can tell after sifting through the code, tol is generally compared to the distance between the zero and pole under test. However, the tol that is used is modified from what the user provides. This modification is very small, except when checking for cancellations of poles and zeros on (or perhaps very close to?) the imaginary axis, which includes the origin.
For example,
H = zpk(-3e-8,0,1);
minreal(H,1e-7) % real pole/zero at/near the origin
ans = (s+3e-08) --------- s Continuous-time zero/pole/gain model.
H = zpk(-1-3e-8,-1,1); % real pole/zero at -1 separated by 3e-8
minreal(H,1e-7)
ans = 1 Static gain.
minreal(H,3e-8) % exact tol, cancellation occurs
ans = 1 Static gain.
H = zpk(1j*(1-3e-8)*[1 -1] ,[-j,j],1) % imaginary pole/zero at 1j separated by 3e-8
H = (s^2 + 1) --------- (s^2 + 1) Continuous-time zero/pole/gain model.
minreal(H,3e-7) % doesn't cancel
ans = (s^2 + 1) --------- (s^2 + 1) Continuous-time zero/pole/gain model.
minreal(H,3e-4) % need a larger tolerance
ans = 1 Static gain.
H = zpk(-1+1j*(1-3e-8)*[1 -1] ,-1+[-j,j],1) % complex poles and zeros separated by 3e-8
H = (s^2 + 2s + 2) -------------- (s^2 + 2s + 2) Continuous-time zero/pole/gain model.
minreal(H,3e-7) % cancels
ans = 1 Static gain.
I don't know if this helps, but it shows that poles/zeros around the origin and on the imaginary axis are treated a bit differently than those that aren't.
##### 2 CommentsShowHide 1 older comment
Paul on 28 Nov 2022
If I had to guess, I suspect that the idea might be that a pole/zero pair that are close to each other AND on or near the imaginary axis can have a larger effect on the frequency response than a pole/zero pair that are just as close to each other but further from the imaginary axis. If this is the case, then maybe they are trying to protect the user in some sense.
H = zpk(-2+1j*(1-3e-8)*[1,-1] ,-2+1j*[1,-1],1) % imaginary pole/zero at -2+1j separated by 3e-8
H = (s^2 + 4s + 5) -------------- (s^2 + 4s + 5) Continuous-time zero/pole/gain model.
bode(H,logspace(-1,1,50000)) H = zpk(-0.01+1j*(1-3e-8)*[1,-1] ,-0.01+1j*[1,-1],1) % imaginary pole/zero at -0.01+1j separated by 3e-8
H = (s^2 + 0.02s + 1) ----------------- (s^2 + 0.02s + 1) Continuous-time zero/pole/gain model.
bode(H,logspace(-1,1,50000)) The effect of the latter on the frequency response is three orders of magnitude higher than the former ( realize that this might not be the best example). Anyway, just a guess on my part. Whatever the reason, the doc should at least mention that tol is not always explicitly adhered to under certain condtions.