Resulta que el método trapezoidal no es preciso cuando se utiliza en los datos lineales. La aproximación lineal por partes solo es precisa en el gráfico log-log. Como no he encontrado una buena fuente detallada sobre el tema, hice los cálculos.
Función \ $ \ mathscr {L} (f) \ $ pasando por \ $ (f_1, \ mathscr {L} _1) \ $ y \ $ (f_2, \ mathscr {L} _2) \ $, como línea en una figura de log-log:
\ begin {equation}
log_ {10} (\ mathscr {L} (f)) = \ frac {1} {10} \ frac {\ mathscr {L} _ {2 | dBc} - \ mathscr {L} _ {1 | dBc}} {log_ {10} (f_2) -log_ {10} (f_1)} log_ {10} (f) + \ frac {1} {10} \ frac {log_ {10} (f_2) \ mathscr {L} _ { 1 | dBc} -log_ {10} (f_1) \ mathscr {L} _ {2 | dBc}} {log_ {10} (f_2) -log_ {10} (f_1)}
\ end {ecuación}
Esto puede ser reescrito como:
\ begin {equation}
\ begin {alineado}
\ mathscr {L} (f) & = 10 ^ {a \ cdot log_ {10} (f) + b} = 10 ^ {log_ {10} (f ^ a)} 10 ^ b = f ^ a10 ^ b \\
a & = \ frac {\ mathscr {L} _ {2 | dBc} - \ mathscr {L} _ {1 | dBc}} {10 (log_ {10} (f_2) -log_ {10} (f_1)) } \ qquad b = \ frac {log_ {10} (f_2) \ mathscr {L} _ {1 | dBc} -log_ {10} (f_1) \ mathscr {L} _ {2 | dBc}} {10 (log_ {10} (f_2) -log_ {10} (f_1))}
\ end {alineado}
\ end {ecuación}
Integración de \ $ \ mathscr {L} (f) \ $ de \ $ f_1 \ $ a \ $ f_2 \ $:
\ begin {equation}
\ int_ {f_1} ^ {f_2} 2 \ mathscr {L} (f) df = 2 \ cdot10 ^ b \ int_ {f_1} ^ {f_2} f ^ a df = 2 \ frac {f_2 ^ {a + 1} -f_1 ^ {a + 1}} {a + 1} 10 ^ b
\ end {ecuación}
Con múltiples segmentos:
\ begin {equation}
\ begin {alineado}
& \ int 2 \ mathscr {L} (f) df = 2 \ sum \ frac {f_ {i + 1} ^ {a_i + 1} -f_i ^ {a_i + 1}} {a_i + 1} 10 ^ { b_i} \\
a_i & = \ frac {\ mathscr {L} _ {i + 1 | dBc} - \ mathscr {L} _ {i | dBc}} {10 (log_ {10} (f_ {i + 1}) - log_ {10} (f_i))} \ qquad b_i = \ frac {log_ {10} (f_ {i + 1}) \ mathscr {L} _ {i | dBc} -log_ {10} (f_i) \ mathscr {L } _ {i + 1 | dBc}} {10 (log_ {10} (f_ {i + 1}) - log_ {10} (f_i))}
\ end {alineado}
\ end {ecuación}
El código de Python se cambia a:
import numpy as np
f = np.array([1e0,1e1, 1e2, 1e3, 1e4, 1e5])
Lf = np.array([-50,-70,-113,-128,-135,-140])
f0 = 10e6
# f_{i}, f_{i+1}, L_{i}, L_{i+1}
fi = f[:-1]
fip1 = f[1:]
Li = Lf[:-1]
Lip1 = Lf[1:]
ai = (Lip1-Li) / (np.log10(fip1) - np.log10(fi)) /10.0
bi = (Li*np.log10(fip1)-Lip1*np.log10(fi)) / (np.log10(fip1) - np.log10(fi)) /10.0
Sphi = 2*np.sum( 10.0**(bi) * (fip1**(ai+1)-fi**(ai+1))/(ai+1) )
jitter = 1.0/2/np.pi/f0 * np.sqrt(Sphi)
print jitter * 1e12,
print 'ps'
raw_input('done')
La salida es 68.66 ps, coincide con las herramientas en línea.
Todavía estoy interesado si alguien tiene una fuente más completa sobre este tema o un método más simple.