Intermodulation products (third order) from MATLAB and FFT are too low
20 views (last 30 days)
Show older comments
Hi,
The intermodulation products I get from an FFT are too low but they scale correctly against my wanted frequency signal power, at a 3:1 ratio which is correct according to the theory. http://www.electronicdesign.com/what-s-difference-between/what-s-difference-between-third-order-intercept-and-1-db-compression-point
Is there any fundamental reason why MATLAB may not produce intermodulation values at what they should be?
I have developed a script that takes two closely spaced frequencies combined in a waveform and put them through an amplifier transfer curve. The transfer curve is from actual amplifier data.
The amplitude of the waveform before amplification is scaled to what the amplitude should be after amplification. Due to the nature of the amplifier transfer curve, the scaling is non linear at higher amplitudes. This should cause intermodulation, I see the intermodulation on an FFT and record their values.
Unfortunately, the intermodulation values are too low. I know this because my Third Order Intercept point is too high compared to real data. https://en.wikipedia.org/wiki/Third-order_intercept_point
Any Advise would be appreciated.
13 Comments
Answers (3)
David Goodmanson
on 9 Feb 2018
Edited: David Goodmanson
on 14 Feb 2018
Hi Nathan,
I ran my old toi code and came up with 24 dBm = -6 dBW which is pretty close to what you are looking for. The code is not very sophisticated compared to what the toi function in the Signal Processing toolbox can do, but it's a reasonable answer.
Before doing that I took the gain curve from test_help.m and fit it to a parabola ~~ ( constant - v_in_tc^2 ). That's in plot 1 and I think you will agree that the fit is pretty good. This simple gain curve does not ever saturate but it is good somewhat past the 1dB compression point before it goes funny (fig 2). In this model if you include the linear gain curve you can calculate right through the toi without extrapolating, although I used a well known expression to calculate it anyway for small input values.
The code uses A for input amplitudes, B for output amplitudes. Result is Btoi_dBm = 24.1078
(get v_in_tc and v_out_tc, length 51)
Atc = v_in_tc(:)'; % row vectors
Btc = v_out_tc(:)';
A = (0:.0001:6e-3); % wider set of input values
gaincurve = Btc./Atc;
% fit the curve with gainfit = glin*(1 - Ain^2/C^2)
M = [ones(size(Atc))', -(Atc.^2)']; % mini vandermonde matrix
c = M\gaincurve';
glin = c(1); % linear gain
C = sqrt(glin/c(2));
gainfit = glin*(1-A.^2/C^2);
% find gain curve for one input frequency as a check
A0 = sqrt(3/4)*C;
G = @(glin,A0,yin) glin*yin.*(1 - yin.^2/A0^2);
Azero = zeros(size(A));
B = toifun(G,glin,A0,A,Azero); % freq. 1 input only, no freq. 2
gaincheck = B(2,:)./A; % frequency 1 output, then /input
% find the point 1 dB down on the gainfit curve
dB1 = 10^(-1/20); % factor for 1dB down
Ad = sqrt(1-dB1)*C;
Bd = glin*Ad*(1 -Ad^2/C^2);
figure(1)
plot(Atc,gaincurve,A,gainfit,A,gaincheck,Ad,Bd/Ad,'o') % Ain vs gain
grid on
% find toi
nstart = -5;
nfin = -1;
ptsdec = 20;
A1 = logspace(nstart,nfin,(nfin-nstart)*ptsdec+1);
A2 = A1;
B = toifun(G,glin,A0,A1,A2);
Blin = glin*A2;
Binter = B(4,:); % output at freq. 2*f2-f1
Bf2 = B(3,:) % output at freq.f2
Atoi = A2.*sqrt(Blin./Binter); % vector of toi calculations
Atoi = Atoi(round(length(A2)/3)) % pick a representative value
Btoi = glin*Atoi;
% results; convert to dBm
glin_dB = 20*log10(glin)
Ad_dBm = v2dbm(Ad) % 1 dB compression point, input
Atoi_dBm = v2dbm(Atoi) % third order intercept, input
Bd_dBm = v2dbm(Bd) % 1 dB compression point, output
Btoi_dBm = v2dbm(Btoi) % third order intercept, output
figure(2)
loglog(A1,Bf2,A1,Binter,A1,Blin) % Ain vs linear (f2) and intermod (2*f2-f1) amplitudes
grid on
function B = toifun(G,glin,A0,A1,A2)
% row vectors A1,A2 are input amplitudes of two cosine waves f1,f2, f1<f2
% B is an 8 row matrix of output amplitudes whose rows have frequencies:
% 2*f1-f2, f1, f2, 2*f2-f1, 3*f1, 2*f1+f2, 2*f2+f1, 3*f2
nA = length(A1);
B = zeros(8,nA);
% make a time array; delf = 1 for fft frequency array
N = 1e3;
t = (0:N-1)/N;
f1 = 10;
f2 = 11;
y1 = cos(2*pi*f1*t);
y2 = cos(2*pi*f2*t);
ind = [2*f1-f2 f1 f2 2*f2-f1 3*f1 2*f1+f2 2*f2+f1 3*f2] +1;
for k = 1:nA
yin = A1(k)*y1 + A2(k)*y2;
yout = G(glin,A0,yin);
z = fft(yout)/N;
B(:,k) = abs(2*z(ind));
end
end
function dBm = v2dbm(Vrms)
% dBm from Vrms
% dBm = v2dbm(Vrms)
dBm = 10*log10(Vrms.^2/50) + 30;
end
0 Comments
Nathan Kennedy
on 13 Feb 2018
Edited: Nathan Kennedy
on 9 May 2018
5 Comments
David Goodmanson
on 27 Feb 2018
Hi Nathan, I got nearestpoint and I get the figures now but not the plots from 'vline' because that function is not around. Fig 103 shows for third order amplitude a line that drops for awhile and then rises, so there are problems there.
David Goodmanson
on 25 Mar 2018
Hi Nathan,
It looks like you are getting closer, but there are still some steps to go. I think that the most likely reason for the 6dB disagreement is the following. The fft of cos(2pi f t) has a peak at +f and a peak at -f, each of amplitude 1/2. So if you are looking at the positive frequency peaks only, those have to be doubled (except for the one at frequency 0) to get back to amplitude 1.
Whatever the reason, if you correct the linear peaks by a factor of 2, then to make the toi come out in the same spot the third order peaks will have to get larger by a factor of 8, so there is still work to do.
Suppose there is a test function (I won't call it a gain curve yet) such that
yout = C1 [ A cos(2pi f1 t) + A cos(2pi f2 t) ] % C1 is linear gain
+ C2 [ A cos(2pi f1 t) + A cos(2pi f2 t) ]^2
+ C3 [ A cos(2pi f1 t) + A cos(2pi f2 t) ]^3 % assume C3 <0 for compression
+ C4 [ A cos(2pi f1 t) + A cos(2pi f2 t) ]^4
etc
Then looking at C1 and C3 only,
yout =
C1 A [cos(2pi f1 t) + cos(2pi f2 t)]
+ C3 A^3 *
[ (9/4)(cos(2pi ( f1 ) t) + cos(2pi ( f2 ) t)) % fundamental
+ (3/4)(cos(2pi (2f1-f2) t) + cos(2pi (2f2-f1) t)) % low freq intermods
+ (3/4)(cos(2pi (2f1+f2) t) + cos(2pi (2f2+f1) t)) % high freq intermods
+ (1/4)(cos(2pi (3f1 ) t) + cos(2pi (3f2 ) t)) ] % triple freq
For the C3 part the first two lines are nearby to f1, f2 and the third and fourth lines are up around 3f1,3f2.
C3 contributes to the fundamentals f1,f2 but that comes in as A^3 and does not contribute to toi (it definitely contributes to the 1dB compression). Only the C3 term is responsible for toi. Since none of the other C terms come in as A^3 they might mess things up, but they can't possibly contribute to toi. I agree with you that doing a fit containing C4…C10 overcomplicates things and probably reduces the C3 term. In my code I even got rid of C2.
In this situation you can calculate toi which is (C3 being negative)
sqrt((4/3)*C1/(-C3)) % input
C1*sqrt((4/3)*C1/(-C3)) % output
I think it is a good idea to take a simple case where everything is in terms of peak amplitude in volts, such as
C1 = 200
C3 = -2e6
A = input amplitude, range from 1e-5 to 1e-1
and get the code to replicate the known answer
toi = 0.0115 % input
= 2.3094 % output
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!