How to plot AM/AM and AM/PM Characteristic using input and output baseband signals?

I have .txt files that contain complex input and output baseband signals of an amplifier. I need to plot the AM/AM (magnitude of Gain vs. Input power) and AM/PM (phase of Gain vs. Input power) Characteristic.
% Calculate input and output power
P_in = 30 + 10*log10( (abs(x_in).^2)/100); % x_in is the input baseband signal
P_out = 30 + 10*log10((abs(x_out).^2)/100); % x_out is the output baseband signal
% Calculate gain
Mag_Gain = P_out - P_in;
Phase_Gain = rad2deg((angle(x_out) - angle(x_in)));
% Then I plot the AM/AM and AM/PM curves
% however the results does not match with the theoretical results.
% Is the way for calculating the power correct?

1 件のコメント

Laxmikant
Laxmikant 2025 年 1 月 17 日
Hi Zainab,
Have you find the right way to to get AM-AM plot and AM-PM plot?
could you share your result?
I also have PA input singal and output signal from PA but not sure I am doing things in right way or not. My AM-AM plot is spread over large area.
Thank you.

サインインしてコメントする。

 採用された回答

Aditya
Aditya 2024 年 11 月 21 日

0 投票

Hi Zainab,
There's limited information to fully address your query, but from the equations you've shared, your calculations for power seem correct. Here are a few things you might consider to resolve the issue:
  1. Check Unit Consistency: Ensure that all units (e.g., dBm, dB) are consistent throughout your calculations.
  2. MATLAB Central Resource: You might find this MATLAB Central File Exchange post helpful: https://www.mathworks.com/matlabcentral/fileexchange/173930-plots-am-am-and-am-pm?s_tid=answers_rc2-1_p4_MLT
If this doesn't resolve the issue, please attach the output that you are getting and the theoretical output.

1 件のコメント

Zainab Riyadh
Zainab Riyadh 2024 年 11 月 23 日
編集済み: Zainab Riyadh 2024 年 11 月 23 日
Thank you for your response.
Is there documentation for building digital predistortion Lookup tables based on LUT of the PA and gain?

サインインしてコメントする。

その他の回答 (1 件)

Mark
Mark 2026 年 7 月 1 日
Good question — your formula for power is actually fine (assuming peak voltage into 50 ohms), but there are at least three issues that might be causing the mismatch with theory.
Issue 1: Time Alignment (the #1 problem)
Real amplifiers introduce delay between input and output. If the signals aren't aligned sample-by-sample, the phase difference is meaningless and even the AM/AM curve shows false hysteresis. You should time-align first:
% Cross-correlate to find delay
[c, lags] = xcorr(x_out, x_in);
[~, idx] = max(abs(c));
delay = lags(idx);
% Align
if delay >= 0
x_out_aligned = x_out(delay+1:end);
x_in_aligned = x_in(1:end-delay);
else
x_in_aligned = x_in(-delay+1:end);
x_out_aligned = x_out(1:end+delay);
end
Issue 2: AM/AM and AM/PM Are Curves, Not Scatter Clouds
AM/AM and AM/PM represent a memoryless input-output characteristic — one output amplitude for each input amplitude. With a modulated signal, you have thousands of samples at different instantaneous power levels. You need to sort by input power and smooth/bin to extract the characteristic curve:
% Compute instantaneous quantities (after alignment)
mag_in = abs(x_in_aligned);
mag_out = abs(x_out_aligned);
% AM/AM: gain magnitude vs input power
gain_dB = 20*log10(mag_out ./ mag_in);
P_in_dBm = 20*log10(mag_in) - 10*log10(50) + 30; % peak voltage, 50 ohm
% AM/PM: phase shift vs input power
phase_shift = rad2deg(angle(x_out_aligned ./ x_in_aligned));
% Sort by input power
[P_in_sorted, sortIdx] = sort(P_in_dBm);
gain_sorted = gain_dB(sortIdx);
phase_sorted = phase_shift(sortIdx);
% Bin-average to get clean curves (e.g., 0.5 dB bins)
binEdges = floor(min(P_in_sorted)):0.5:ceil(max(P_in_sorted));
numBins = numel(binEdges) - 1;
gain_curve = zeros(numBins, 1);
phase_curve = zeros(numBins, 1);
pin_curve = zeros(numBins, 1);
for k = 1:numBins
mask = P_in_sorted >= binEdges(k) & P_in_sorted < binEdges(k+1);
if any(mask)
gain_curve(k) = mean(gain_sorted(mask));
phase_curve(k) = mean(phase_sorted(mask));
pin_curve(k) = (binEdges(k) + binEdges(k+1)) / 2;
end
end
% Remove empty bins
valid = gain_curve ~= 0 | phase_curve ~= 0;
pin_curve = pin_curve(valid);
gain_curve = gain_curve(valid);
phase_curve = phase_curve(valid);
Issue 3: Use angle(x_out./x_in), Not angle(x_out) - angle(x_in)
Subtracting angles can produce ±360° jumps when the phases wrap independently. Dividing the complex signals first gives a clean single-valued phase difference:
% Wrong (wrapping artifacts):
phase_bad = rad2deg(angle(x_out) - angle(x_in));
% Correct:
phase_good = rad2deg(angle(x_out ./ x_in));
Complete Plotting Code
figure;
tiledlayout(1,2)
nexttile
plot(pin_curve, gain_curve, 'LineWidth', 1.5)
xlabel('Input Power (dBm)')
ylabel('Gain (dB)')
title('AM/AM')
grid on
nexttile
plot(pin_curve, phase_curve, 'LineWidth', 1.5)
xlabel('Input Power (dBm)')
ylabel('Phase Shift (degrees)')
title('AM/PM')
grid on
About The Power Formula
P_in = 30 + 10*log10((abs(x_in).^2)/100);
This is correct if x_in is peak voltage in volts and the system impedance is 50 ohms (|V_peak|² / (2×50) = watts, then 10*log10 + 30 = dBm). But it's not causing the curve mismatch — the three issues above probably are.
Summary
(1) Time-align input and output with cross-correlation before anything else.
(2) Sort by input power and bin-average to extract a clean AM/AM and AM/PM curve — sample-by-sample plotting gives a scatter cloud.
(3) Use angle(x_out./x_in) instead of subtracting angles to avoid wrapping artifacts.

製品

リリース

R2024a

タグ

質問済み:

2024 年 11 月 21 日

回答済み:

2026 年 7 月 1 日

Community Treasure Hunt

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

Start Hunting!

Translated by