Skip to content

Instantly share code, notes, and snippets.

@raytroop
Last active June 8, 2026 14:52
Show Gist options
  • Select an option

  • Save raytroop/ba45a09dfa5abfe3560a355d5ba05d65 to your computer and use it in GitHub Desktop.

Select an option

Save raytroop/ba45a09dfa5abfe3560a355d5ba05d65 to your computer and use it in GitHub Desktop.
"""
Inductive shunt peaking: bandwidth, peak frequency, and peaking gain
as functions of m = R^2 * C / L.
All frequencies are normalized to 1/RC (i.e. the plotted value is omega * RC).
Smaller m <=> larger inductor L.
Impedance: Z(s)/R = (1 + s L/R) / (1 + s R C + s^2 L C)
With u = (omega * RC)^2 and m = R^2 C / L:
|Z/R|^2 = (1 + u/m^2) / ((1 - u/m)^2 + u)
"""
import numpy as np
import matplotlib.pyplot as plt
ONSET = 1 + np.sqrt(2) # m = 2.4142 : peaking switches on
MAX_BW = np.sqrt(2) # m = 1.4142 : maximum bandwidth (approx)
def bandwidth(m):
"""-3 dB bandwidth in units of 1/RC (i.e. omega_3dB * RC)."""
B = 2 + 2 * m - m ** 2
u = (B + np.sqrt(B ** 2 + 4 * m ** 2)) / 2
return np.sqrt(u)
def u_peak(m):
"""(omega_peak * RC)^2 at the magnitude peak; 0 where no peak exists."""
u = m * np.sqrt(1 + 2 * m) - m ** 2
return np.where((m < ONSET) & (u > 0), u, 0.0)
def peak_freq(m):
"""Peak frequency in units of 1/RC."""
return np.sqrt(u_peak(m))
def peak_gain_db(m):
"""Peaking gain in dB (0 dB where the response is monotonic)."""
u = u_peak(m)
num = 1 + u / m ** 2
den = (1 - u / m) ** 2 + u
with np.errstate(divide="ignore", invalid="ignore"):
g = 10 * np.log10(num / den)
return np.where(u > 0, g, 0.0)
m = np.linspace(0.3, 5, 400)
fig, ax1 = plt.subplots(figsize=(9, 5))
ax2 = ax1.twinx()
l1, = ax1.plot(m, bandwidth(m), color="#0f6e56", lw=4,
label="bandwidth (×1/RC)")
l2, = ax1.plot(m, peak_freq(m), color="#d85a30", lw=4, ls="-",
label="peak freq (×1/RC)")
l3, = ax2.plot(m, peak_gain_db(m), color="#534ab7", lw=4, ls="-",
label="peaking gain (dB)")
for mv, txt in [(MAX_BW, "max BW (m≈1.41)"), (ONSET, "peaking onset (m≈2.41)")]:
ax1.axvline(mv, color="0.6", ls="--", lw=1)
ax1.text(mv - 0.04, 1.96, txt, rotation=90, va="top", ha="right",
fontsize=9, color="0.4")
ax1.set_xlabel("m = R²C / L (← larger L smaller L →)", fontsize=14)
ax1.set_ylabel("frequency (×1/RC)", fontsize=14)
ax2.set_ylabel("peaking gain (dB)", fontsize=14, color="#534ab7")
ax2.tick_params(axis="y", colors="#534ab7")
ax1.set_xlim(0.3, 5)
ax1.set_ylim(0, 2)
ax2.set_ylim(0, 12)
ax1.set_title("Shunt peaking: bandwidth, peak frequency, peaking gain vs m", fontsize=16)
ax1.grid(alpha=0.25)
ax1.legend(handles=[l1, l2, l3], loc="upper right", framealpha=0.9)
plt.tight_layout()
plt.savefig("shunt_peaking_metrics.png", dpi=150)
plt.show()
<h2 class="sr-only">Bandwidth, peak frequency, and peaking gain for inductive shunt peaking, all plotted against m equals R squared C over L. Frequencies are in units of 1 over RC. Bandwidth and peak frequency are humps peaking near m of 1.3 to 1.4; peaking gain decreases monotonically and reaches zero at m equals 2.41.</h2>
<div style="display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 10px; font-size: 12px; color: var(--color-text-secondary);">
<span style="display:flex;align-items:center;gap:6px;"><span style="width:18px;height:0;border-top:2px solid #0f6e56;"></span>bandwidth (&times;1/RC) &nbsp;(left)</span>
<span style="display:flex;align-items:center;gap:6px;"><span style="width:18px;height:0;border-top:2px dashed #d85a30;"></span>peak freq (&times;1/RC) &nbsp;(left)</span>
<span style="display:flex;align-items:center;gap:6px;"><span style="width:18px;height:0;border-top:2px dotted #534ab7;"></span>peaking gain dB &nbsp;(right)</span>
</div>
<div style="position: relative; width: 100%; height: 340px;">
<canvas id="three2" role="img" aria-label="Three curves versus m equals R squared C over L from 0.3 to 5. Bandwidth, in units of 1 over RC, rises to about 1.85 near m of 1.4 then falls toward 1. Peak frequency, in units of 1 over RC, rises to about 0.88 near m of 1.3 then drops to zero at m of 2.41. Peaking gain falls monotonically from over 11 dB at small m to zero at m of 2.41 and stays zero.">Bandwidth and peak frequency (in units of 1/RC) are humps peaking near m of 1.3 to 1.4; peaking gain decreases monotonically to zero at m of 2.41.</canvas>
</div>
<p style="font-size:12px;color:var(--color-text-tertiary);margin:6px 0 0;text-align:center;">&larr; larger L &nbsp;&middot;&nbsp; m = R&sup2;C/L &nbsp;&middot;&nbsp; smaller L &rarr; &nbsp;|&nbsp; dashed lines: m = 1.41 (max BW), m = 2.41 (peaking onset)</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js"></script>
<script>
(function(){
var ONSET = 2.414214;
function bw(m){ var B=2+2*m-m*m; var u=(B+Math.sqrt(B*B+4*m*m))/2; return Math.sqrt(u); }
function up(m){ if(m>=ONSET) return 0; var u=m*Math.sqrt(1+2*m)-m*m; return u>0?u:0; }
function pf(m){ return Math.sqrt(up(m)); }
function pg(m){ var u=up(m); if(u<=0) return 0; var num=1+u/(m*m); var den=Math.pow(1-u/m,2)+u; return 10*Math.log10(num/den); }
var dBW=[], dPF=[], dPG=[];
for(var i=0;i<=200;i++){
var m=0.3+(i/200)*(5-0.3);
dBW.push({x:m,y:bw(m)}); dPF.push({x:m,y:pf(m)}); dPG.push({x:m,y:pg(m)});
}
var markers={ id:'mk', afterDraw:function(c){
var ctx=c.ctx, xs=c.scales.x, a=c.chartArea;
[1.41,2.41].forEach(function(v){
var px=xs.getPixelForValue(v); ctx.save();
ctx.strokeStyle='rgba(136,135,128,0.55)'; ctx.setLineDash([4,3]); ctx.lineWidth=1;
ctx.beginPath(); ctx.moveTo(px,a.top); ctx.lineTo(px,a.bottom); ctx.stroke(); ctx.restore();
});
}};
new Chart(document.getElementById('three2'), {
type:'line',
data:{ datasets:[
{ label:'bandwidth', data:dBW, yAxisID:'y', borderColor:'#0f6e56', borderWidth:2.4, pointRadius:0, tension:0.25 },
{ label:'peakfreq', data:dPF, yAxisID:'y', borderColor:'#d85a30', borderWidth:2.2, borderDash:[7,4], pointRadius:0, tension:0.25 },
{ label:'peakgain', data:dPG, yAxisID:'y1', borderColor:'#534ab7', borderWidth:2.2, borderDash:[2,3], pointRadius:0, tension:0.25 }
]},
plugins:[markers],
options:{ responsive:true, maintainAspectRatio:false,
interaction:{ mode:'index', intersect:false },
plugins:{ legend:{display:false},
tooltip:{ callbacks:{ title:function(it){ return 'm = '+(+it[0].parsed.x).toFixed(2); },
label:function(it){ var n=it.datasetIndex; var v=it.parsed.y;
return n===0?('bandwidth: '+v.toFixed(2)+' ×1/RC'):n===1?('peak freq: '+v.toFixed(2)+' ×1/RC'):('peaking gain: '+v.toFixed(2)+' dB'); } } } },
scales:{
x:{ type:'linear', min:0.3, max:5,
title:{display:true, text:'m = R²C / L', color:'#888780', font:{size:12}},
ticks:{ color:'#888780', font:{size:11} }, grid:{ color:'rgba(136,135,128,0.15)' } },
y:{ position:'left', min:0, max:2,
title:{display:true, text:'frequency (×1/RC)', color:'#888780', font:{size:12}},
ticks:{ color:'#888780', font:{size:11} }, grid:{ color:'rgba(136,135,128,0.15)' } },
y1:{ position:'right', min:0, max:12,
title:{display:true, text:'peaking gain (dB)', color:'#534ab7', font:{size:12}},
ticks:{ color:'#534ab7', font:{size:11} }, grid:{ drawOnChartArea:false } }
}
}
});
})();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment