5 views (last 30 days)

I am stumped by the behaviour of evalfr vs freqresp in the control systems toolbox. They claim to give the same results, but when their arguments are purely real there is a (large!) discrepancy. I am inclined to believe the results from evalfr; for all sane transfer functions a real value of s should result in a real value of the transfer function.

With the following code:

G = tf([1],[1 1]);

wc = 3+1e-10*1i;

[evalfr(G,wc);freqresp(G,wc)]

Both give the answer 0.2500-0.0000i.

When the input is purely real, however:

G = tf([1],[1 1]);

wc = 3;

[evalfr(G,wc);freqresp(G,wc)]

ans =

0.2500 + 0.0000i

0.1000 - 0.3000i

I'm using Matlab 2020a and I believe this behaviour has been around for a while; I came across an old code comment that said something like "don't use freqresp -- evalfr gives proper results here". Fine for me, but harder to advise when teaching students...

Devineni Aslesha
on 26 May 2020

Hi Will,

I have brought the issue of 'freqresp accepting frequency input with non-zero imaginary part' to the notice of our developers. They will investigate the matter further.

Zhao Wang
on 28 May 2020

I would like to comment about the second point. If c is nonzero, no matter how small it is, the w is treated as a complex number. As a result, it is interpreted as s or z value in the transfer functions. The frequency response result would be different because the real value r would still be treated as the frequency value in freqresp(G,r).

You will get the same result using freqresp(G, r+0*1j) and freqresp(G,r) because r+0*1j and r are both treated as real values. For example, here is what I got:

>> freqresp(G,3)

ans = 0.1000 - 0.3000i

>> freqresp(G,3+0*j)

ans = 0.1000 - 0.3000i

Paul
on 3 Jun 2020

- I agree with Will on point 1. The documenation is crystal clear. The input w must be real and the output is defined using the standard definition of freuqency response for either a continous or discrete system. I'm not sure why there's any reason for freqresp to accept an input with non-zero imaginary part. One might think that it should for backwards compatibility with the old version of freqresp (which is still usable, see my example below). But IMO that argument doesn't work because freqresp as currently implemented already has a different behavior than the old version for a real input. So that backwards compatibilty was lost anyway. At the very least, if freqresp is going to continue to accept complex inputs, it should generate a warning that that's unodocumented behavior, and it should be deprecated. And the same goes for the old version of freqresp.
- Zhao, I can't comment on Will's point. But freqresp does return inconsistent results. Please check my example below that shows freqresp (the current version) returns different outputs for the same input. Surely that can't be acceptable.
- As to Will's point 3, I agree that the documentation for evalfr is misleading. In fact, I think the name of the function is misleading. It should be evaltf. The very description says: "evaluates the transfer function ..." (emphasis added).
- As has been well established we have for continuous time systems: evalfr(G,1j*w) == freqresp(G,w) with w real. I'd like to add that if G is a model for a discrete time system then we have: evalfr(G,exp(1j*w*G.Ts) == freqresp(G,w) if G.Ts is defined and w is real, and evalfr(G,exp(1j*w) == freqresp(G,w) if G.Ts is undefined.
- The doc pages for evalfr and freqresp are pretty weak at explaining how these functions relate to each other, and the "More About" and "Algorithm" sections of doc freqresp are weak at explaining the discrete time case.

Paul
on 24 May 2020

evalfr evalutes the transfer function at the value of the input argument, which can be an arbitrary complex number. For your example, evalfr(G,wc) = G(wc).

freqresp evaluates the frequency response at the value of the input argument, which must be real (doc freqresp). Because it's the frequency response, freqresp(G,wc) = G(1j*wc) (as long as wc is real).

So if you want to compute the frequency response of G using evalfr, you have to multiply the (real) input by 1j:

>> wc = 3; [evalfr(G,1j*wc); freqresp(G,wc)]

ans =

0.1000 - 0.3000i

0.1000 - 0.3000i

If you want to evaluate the transfer function of G at a complex number with non-zero real part, then your only choice is evalfr(G,s).

Check the doc pages for both functions.

Having said that, in 2019a the doc page for evalfr is missing the sections for the details on the input and output arguments. But it's all pretty clear from what is shown on that doc page.

Paul
on 25 May 2020

Will,

My statement that you quoted was intendended to be general in that I was thinking that 3, as in your example, is a complex number. I'm also suprised that freqresp (for a tf object like G, and probaby for its superclasses) accepts a frequency input with a non-zero imaginary part. And the situation is even worse than I thought. Consider:

>> G=tf(1,[1 1]);h1=freqresp(G,3);h2=freqresp(G,[3; 1+3*1i]);[h1 h2(1)]

ans =

0.1000 - 0.3000i 0.2500 + 0.0000i

freqresp computed a different output for the same input. Which is troubling. Though I can't say it's a bug because that second call to compute h2 is invalid anyway.

Then on top of this, the old-style use of freqresp is still usable, though I'm not sure if it's still supported functionality:

>> freqresp(1,[1 1],3)

ans =

0.2500

Apprarently freqresp used to work like evalfr works now.

Opportunities for recent engineering grads.

Apply TodayFind the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
## 2 Comments

## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/526114-freqresp-gives-wrong-output-for-purely-real-inputs#comment_856753

⋮## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/526114-freqresp-gives-wrong-output-for-purely-real-inputs#comment_856753

## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/526114-freqresp-gives-wrong-output-for-purely-real-inputs#comment_856883

⋮## Direct link to this comment

https://in.mathworks.com/matlabcentral/answers/526114-freqresp-gives-wrong-output-for-purely-real-inputs#comment_856883

Sign in to comment.