7

次のように、「超ガウス」関数を生成してプロットするための Python コードを書いています。

def supergaussian(x, A, mu, sigma, offset, N=8):
    """Supergaussian function, amplitude A, centroid mu, st dev sigma, exponent N, with constant offset"""
    return A * (1/(2**(1+1/N)*sigma*2*scipy.special.gamma(1+1/N))) * numpy.exp(-numpy.absolute(numpy.power(x-mu,N))/(2*sigma**N)) + offset

init_x = numpy.arange(-100,100,1.0)
init_y = supergaussian(init_x, 1, 0, 25, 0, N=12)

次のコードは、それをプロットするだけです。理解できない理由により、このコードは、デフォルト値の 8NまたはN13 までの値を使用すると正常に動作します。Nが 14 以上の場合、関数はエラー メッセージでクラッシュします。

AttributeError: 'float' object has no attribute 'exp'

関数定義の戻り行。何か案は?その行で .exp を使用するのnumpy.expはエラーメッセージnumpyのみであるため、float として解釈されていることを意味しているように見えますが、N...

私はnumpy 1.7.1とscipy 0.12.0でpython 3.3.2を実行しています

4

1 に答える 1

15

エラーは、numpy dtype の奇妙さによるものです。内部でどのように機能するのか正確にはわかりませんが、何らかの理由2*25**14で Numpy がデータ型を処理する方法が変更されます。

>>> type(np.max(-numpy.absolute(numpy.power(init_x-0,13)))/(2*25**13))
<type 'numpy.float64'>
>>> type(np.max(-numpy.absolute(numpy.power(init_x-0,14)))/(2*25**14))
<type 'float'>

13 ではまだ Numpy の float64 型を使用していますが、14 ではどういうわけか通常の float に戻ります。これが AttributeError を取得する理由です。通常の Python floatexpには、numpy ufunc メソッドであるメソッドがありません。(エラーは、float として解釈される名前によるnumpyものではありません。属性を持たないオブジェクトが何であるかがわからないという点で、これらの numpy 内部エラーは役に立たない場合があります。)

ただし、これは2*25**N数値が numpy データ型の値ではなく、通常の Python long であるためにのみ発生します。次のように、numpy dtype でその値を事前にラップすることで修正できます。

def supergaussian(x, A, mu, sigma, offset, N=8):
    """Supergaussian function, amplitude A, centroid mu, st dev sigma, exponent N, with constant offset"""
    denom = np.float64(2*sigma**N)
    return A * (1/(2**(1+1/N)*sigma*2*scipy.special.gamma(1+1/N))) * numpy.exp(-numpy.absolute(numpy.power(x-mu,N))/denom) + offset

大きな値でも問題なく動作するようになりました。

2*25**14変換の失敗は、大きすぎて numpy int64 に収まらないことが原因のようです。これは私にはバグのように見えます: int64 には大きすぎる場合、float64 にフォールバックするか、エラーを発生させる必要があります。numpy trackerに関連するバグがあるようですが、それは少し違うようです。numpy トラッカーやメーリング リストで問題を提起することをお勧めします。

于 2013-09-16T17:29:30.783 に答える