2016-03-31 7 views

Antwort

5

Sie numpy.sinc verwenden könnte, die sin (pi x berechnet)/(pi x):

In [20]: x = 2.4 

In [21]: np.sin(x)/x 
Out[21]: 0.28144299189631289 

In [22]: x_over_pi = x/np.pi 

In [23]: np.sinc(x_over_pi) 
Out[23]: 0.28144299189631289 

In [24]: np.sinc(0) 
Out[24]: 1.0 
1

In numpy Array-Notation (so dass Sie einen np Array zurück):

def sindiv(x): 
    return np.where(np.abs(x) < 0.01, 1.0 - x*x/6.0, np.sin(x)/x) 

Hier habe ich gemacht „epsilon“ ziemlich groß für die Prüfung und verwendet, um die ersten beiden Terme der Taylor-Reihe für die Angleichung . In der Praxis würde ich 0,01 zu einem kleinen Vielfachen Ihrer eps (Maschine Epsilon) ändern.

xx = np.arange(-0.1, 0.1, 0.001) 
yy = sinxdiv(xx) 
type(yy) 

Ausgänge numpy.ndarray und die Werte kontinuierlich sind (und differenzierbar, wenn die wichtig ist) in der Nähe des Ursprungs.

Wenn Sie nicht wollen, dass die doppelte Auswertung (dh beide Zweige sind in der oben genannten bewertet), dann denke ich, Sie müssen mit einer Schleife gehen, da ich glaube, es gibt keine Art von "faul wo" -Option .

def sindiv(x): 
    sox = np.zeros(x.size) 
    for i in xrange(x.size): 
     xv = x[i] 
     if np.abs(xv) < 0.001: # For testing, use a small multiple of machine epsilon 
      sox[i] = 1.0 - xv * xv/6.0 
     else: 
      sox[i] = np.sin(xv)/xv 
    return sox 

Um dies wirklich pythonic obwohl es am besten wäre, zu prüfen, tun die Art der x und nur die nicht-Array-Version, wenn es kein Array ist.

+0

Aber da beide '1.0 - x * x/6.0' und' np.sin (x)/x' wird berechnet, es gibt noch mehr langsamen Betrieb. Und ein RuntimeWarning wird ausgelöst, wenn x 0 enthält. – eph

+0

Ihre Methode ist nett, wenn Sie etwas wie "sin (x)/x - 1" berechnen. Aber für 'sin (x)/x' nahe' x = 0' wird die Genauigkeit nicht verbessert, da die Float-Auflösung signifikanter ist. Auf der anderen Seite ist die Verwendung von Schleifen langsam und nicht ... – eph

+0

Zustimmen - das ist, warum meine erste Neigung war, wo zu verwenden. Wenn '1' in Ihrem Epsilon gut genug ist, dann ist die 'Where'-Version mit 1 das Beste, was ich mir vorstellen kann. Wie Sie sagten, erhalten Sie eine Warnung, da dies die Argumente vor dem Aufruf von 'where' berechnet. Natürlich, wenn Sie dies viel tun und maximale Geschwindigkeit benötigen, könnten Sie es in C schreiben. – sfjac

0

Wie wäre es, div durch Null zuzulassen und NaNs später zu ersetzen?

import numpy as np 

def sindiv(x): 
    a = np.sin(x)/x 
    a = np.nan_to_num(a) 
    return a 

Wenn Sie keine Warnungen wollen, unterdrücken sie über seterr

Natürlich a mit beseitigt werden könnten:

def sindiv(x): 
    return np.nan_to_num(np.sin(x)/x) 
+0

Das Ergebnis von Div 0 scheint nicht definiert. Ich fand "0" in einer Version von numpy und "inf" in einem anderen ... – eph

+0

@eph, dann ist es wahrscheinlich eine schlechte Idee dann –

+1

Ich überprüfte 'np.divide (1, 0)', es gibt '0' in zurück Python 2 und 'inf' in Python 3. Und' 0' scheint das Ergebnis von floor div zu sein, während 'inf' das Ergebnis von div ist. Wenn also x ein float-Array ist (oder in Python 3 mit true div), scheint div 0 "inf" zu sein. Jetzt ist das Problem "nan_to_num" ersetzt es mit "0", nicht "1". – eph

Verwandte Themen