# The chirp interface has changed in R2019b

15 views (last 30 days)
David De Lorenzo on 2 Oct 2019
Commented: Frantz Bouchereau on 17 Dec 2019
When I call the chirp function in R2019a I can specify negative F0 and F1; now calling the function in 2019b I get an error: "Expected F1 to be nonnegative".
This test code runs in 2019a but errors in 2019b:
fs = 1e3;
t = 0:1/fs:1;
y = chirp(repmat(t,1,4), -400, t(end), -100);
spectrogram(y, 256, 250, 256, 1/diff(t(1:2)));
drawnow();
Thanks!
Dave.
Star Strider on 2 Oct 2019
Interesting. I can find no mention of that in the Release Notes.

Walter Roberson on 2 Oct 2019
f0 Initial instantaneous frequency at time 0, specified as a positive scalar expressed in Hz.
In other words, negative was not valid before, but did not happen to create an error message.
David De Lorenzo on 2 Oct 2019
Thank you - I obviously had not noted that in the API description.
Dave.

David De Lorenzo on 2 Oct 2019
Well, it appears that a workaround is to simply alias up by the sampling frequency:
fs = 1e3;
t = 0:1/fs:1;
f0 = -300+fs;
f1 = -100+fs;
phi = 0;
y = complex(chirp(repmat(t,1,4), f0, t(end), f1, 'linear', rad2deg(phi)), ...
chirp(repmat(t,1,4), f0, t(end), f1, 'linear', rad2deg(phi-pi/2)));
spectrogram(y, 256, 250, 256, 1/diff(t(1:2)), 'centered', 'yaxis');
drawnow();

Robert Kossler on 8 Nov 2019
This is not a good solution. Negative frequency should be allowed as this is a very common engineering practice to work in negative as well as positive frequencies - especially when forming a complex chirp such as:
x = complex(chirp(t,f0,t1,f1,'linear',90),chirp(t,f0,t1,f1,'linear',0));
In this case it is completely normal to expect that both 'f0' and 'f1' can be negative or positive. Asking the user to purposely alias the frequecies to work around this deficiency is unacceptable.
In my opinion, it is not the old function that was in error, but rather the error was in the comment that indicated only positive frequencies were allowed. Mathworks should have changed the comment rather than limiting the function. The old function behaved exactly how it should have even if the comment was inaccurate.

Robert Kossler on 8 Nov 2019
One final comment. It is a big issue that this change in behavior was not included in the release notes. Perhaps since Mathworks was only "fixing" the function to match the comments, it didn't feel the need to put this in the release notes. However, the behavior is undeniably changed since the new function breaks old code. It should have been noted in the release notes.
Walter Roberson on 8 Nov 2019
The release notes have rarely made note of bug fixes.
Repairing the code to match the documentation is not something that would be expected to be mentioned in the release notes.

Robert Kossler on 8 Nov 2019
However, it does not address my contention that Mathworks noticed a discrepancy between the chirp documentation and the chirp code and mistakenly assumed that the documentation was correct and the code was incorrect. Thus, Mathworks "fixed" the code. In actuality, the code was correct and the documentation was incorrect such that Mathworks should have updated the documentation instead and left the code intact. It makes no sense to disallow negative frequencies in the same way it would make no sense to disallow negative phase to any function requiring phase as an input.
Walter Roberson on 8 Nov 2019
The change to the documentation appears to have been R2018b, https://www.mathworks.com/help/releases/R2018b/signal/ref/chirp.html which is the first release in which the datatypes and ranges of the input arguments were documented.
You could open a bug against the R2018b release notes for not documenting the change.

Frantz Bouchereau on 16 Dec 2019
Edited: Walter Roberson on 16 Dec 2019
Hi David.
Chirp does not generate complex outputs, so the results of chirp are only correct when both frequencies are positive (or when both frequencies are negative) in which case you get a correct symmetric spectrum.
A combination of a positive and negative frequencies does not yield a linear or quadratic chirp, instead it generates two chirp segments (not what chirp function promises).
See the figure created with the example code below. Notice that a combination of positive and negative frequencies does not yield a chirp. It generates a symmetric signal consisting of a chirp that goes from -250 to 0 and then another chirp that goes from 0 to -100 Hz. Also notice that specifying 2 negative frequencies is equivalent to specifying 2 positive frequencies. This is the reason why we limited F1 to be positive. Having said that, I noticed that we are actually not checking for F0 to be positive so we need to fix this as well.
The best solution is to allow both frequencies to be either positive, or both frequencies to be negative (although allowing negative frequencies is not really necessary, it will prevent code like the one you wrote from breaking). We will never allow mixed signs to prevent an incorrect answer which was our intent when we updated the code.
For now, notice that in your code:
y = chirp(repmat(t,1,4), -400, t(end), -100);
is equivalent to
y = chirp(repmat(t,1,4), 400, t(end), 100);
Thanks
------------------------- t = 0:1/1000:10;
figure
subplot(3,1,1)
% Two negative frequencies
y = chirp(t,-250,10,-100);
spectrogram(y,128,[],[],1000,'centered','yaxis')
title('Two negative frequencies -> chirp(t,-250,10,-100)')
subplot(3,1,2)
% Two positive frequencies (equivalent to two negative frequencies)
y = chirp(t,250,10,100);
spectrogram(y,128,[],[],1000,'centered','yaxis')
title('Two positive frequencies -> chirp(t,250,10,100)')
subplot(3,1,3)
% One positive frequency and one negative frequency
y = chirp(t,-250,10,100);
spectrogram(y,128,[],[],1000,'centered','yaxis')
title('One positive frequency and one negative frequency- -> chirp(t,-250,10,100)')

Robert Kossler on 16 Dec 2019
Hi Frantz,
Use either the code from David or the code from me earlier in this thread to create a complex chirp using older Matlab that accepts negative freqs. If you only have newer Matlab, then simply change the two frequencies to be positive. Either way you will get a complex chirp with non-symmetric freq.
Rob

Robert Kossler on 16 Dec 2019
Frantz,
Here is some code you can run to utilize freqs from -f0 to f1 using 2018b.
As to the question 'Why would you want to do this?' - Whenever you operate at baseband IQ it is useful to consider positive and negative freqs about the ultimate RF carrier freq.
You mentioned above that chirp produces the same result for positive or negative freqs and that is the reason you got rid of negative freqs. But, you could make the same argument regarding the 'cos' function. It produces the same result for positive and negative arguments. But you would have a lot of unhappy customers if you removed the ability to have a negative argument to the 'cos' function.
And, consider an expression such as 'x(t) = cos(t) + 1i * sin(t)' which I think you will agree is a useful expression. Now, extend that to 'x(t) = chirp(t,90 deg) + 1i * chirp(t, 0 deg)' which is what we are doing with chirp.
Rob
>> t = (0:999)'/1000;
>> t1 = t(end);
>> f0 = -150;
>> f1 = 250;
>> x = complex(chirp(t,f0,t1,f1,'linear',90),chirp(t,f0,t1,f1,'linear',0));
>> spectrogram(x,100,[],[],1000,'centered','yaxis')
>>
Frantz Bouchereau on 17 Dec 2019
Robert, thanks for the use case. You make a very good point. We will revert the check for positive on frequencies. Expect updates on all applicable releases.
In the meantime, the obvious workaround is to remove the 'nonnegative' check in line 193 of chirp.m
validateattributes(input,{'numeric'},{'scalar','real','nonnegative','finite'},'chirp','F1'); -->
validateattributes(input,{'numeric'},{'scalar','real','finite'},'chirp','F1');
Thanks

R2019b

### Community Treasure Hunt

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

Start Hunting!