2010-11-19 10 views
2

Ich habe die folgende Funktion, in der ich aus einer Tabelle bei einem angegebenen Wert interpolieren möchte. Der Trick besteht darin, dass die Tabelle logarithmisch definiert ist, so dass gerade Linien zwischen den Punkten im Log-Log wirklich exponentiell sind. Daher kann ich keine der typischen Interpolationsroutinen verwenden.numpy Magie zu bereinigen Funktion

Also hier ist, was ich habe:

PSD = np.array([[5.0, 0.001], 
       [25.0, 0.03], 
       [30.0, 0.03], 
       [89.0, 0.321], 
       [90.0, 1.0], 
       [260.0, 1.0], 
       [261.0, 0.03], 
       [359.0, 0.03], 
       [360.0, 0.5], 
       [520.0, 0.5], 
       [540.0, 0.25], 
       [780.0, 0.25], 
       [781.0, 0.03], 
       [2000.0, 0.03]]) 

def W_F(freq): 
    ''' 
    A line connecting two points in a log-log plot are exponential 
    ''' 
    w_f = [] 
    for f in freq: 
     index = np.searchsorted(PSD[:,0], f) 
     if index <= 0: 
      w_f.append(PSD[:,1][0]) 
     elif index + 1>= PSD.shape[0]: 
      w_f.append(PSD[:,1][-1]) 
     x0 = PSD[:,0][index-1] 
     F0 = PSD[:,1][index-1] 
     x1 = PSD[:,0][index] 
     F1 = PSD[:,1][index] 
     w_f.append(F0*(f/x0)**(math.log(F1/F0)/math.log(x1/x0))) 
    return np.array(w_f) 

Ich bin für eine bessere, sauberere suchen „numpy-ish“ Weg, um dieses

+1

'für freq = in f:' - ist nur eine Transkription Tippfehler oder funktioniert Ihr Code nicht? Außerdem sollten Sie nicht freq in der vorletzten Zeile anstelle von f verwenden? –

+0

Ja, die Funktion ist falsch. Sollte lauten: – user90855

+0

Ich habe den Fehler korrigiert – user90855

Antwort

3

Der einfachste Weg zur Umsetzung zu gehen, ist zu nehmen, nur die Logarithmus von PSD und dann SciPy Interpolation Funktionen verwenden:

logPSD = numpy.log(PSD) 
logW_F = scipy.interpolate.interp1d(logPSD[:,0], logPSD[:,1]) 
W_F = numpy.exp(logW_F(numpy.log(f))) 

Dies wird einen Fehler für out-of-bounds Werte werfen. Um den Fehler zu vermeiden, könnten Sie

  • Pass bounds_error=False zum interp1d() Funktion finden Sie the documentation.

  • einen Eintrag am Anfang und das Ende der PSD mit einem sehr kleinen und sehr großen x-Wert hinzufügen alle möglichen Werte zu erfassen.

Als Alternative interp1d() zu verwenden, ist es möglich, Ihren Code vektorisieren, aber ich würde dies nur aus einem Grunde tun.

+0

Genau das, was ich gesucht habe. Ich denke, das Protokoll (f) in der letzten Zeile sollte in numpy.log (f) geändert werden – user90855

+0

Ja, Sie haben Recht. Habe den Code nicht getestet :) –