在Enthought Canopy中使用Python的Lambert函数时出现NaN值

2 投票
2 回答
636 浏览
提问于 2025-04-18 06:11

我正在尝试在Python中使用Lambert函数来解决一个问题,但在使用Canopy时,我得到了一个NaN的结果。我的方程式如下:

from scipy.special import lambertw

y=8.21016005323e+158

gama = -339.375260893

x = lambertw(y) + gama

print x

当我在Matlab中执行相同的代码时,我得到了x = 20.6524,这是我想要的结果。

我不太确定这个NaN值是怎么产生的,但我怀疑可能和我y的值太大有关。有没有办法让我在Python中处理这个问题,得到正确的结果呢?

谢谢

scipy.show_config()

   umfpack_info:
  NOT AVAILABLE
lapack_opt_info:
    libraries = ['mkl_lapack95_lp64', 'mkl_core_dll', 'mkl_intel_lp64_dll', 'mkl_intel_thread_dll']
    library_dirs = ['C:\\Users\\vagrant\\src\\master-env\\libs']
    define_macros = [('SCIPY_MKL_H', None)]
    include_dirs = ['C:\\Users\\vagrant\\src\\master-env\\include']
blas_opt_info:
    libraries = ['mkl_core_dll', 'mkl_intel_lp64_dll', 'mkl_intel_thread_dll']
    library_dirs = ['C:\\Users\\vagrant\\src\\master-env\\libs']
    define_macros = [('SCIPY_MKL_H', None)]
    include_dirs = ['C:\\Users\\vagrant\\src\\master-env\\include']
openblas_info:
  NOT AVAILABLE
lapack_mkl_info:
    libraries = ['mkl_lapack95_lp64', 'mkl_core_dll', 'mkl_intel_lp64_dll', 'mkl_intel_thread_dll']
    library_dirs = ['C:\\Users\\vagrant\\src\\master-env\\libs']
    define_macros = [('SCIPY_MKL_H', None)]
    include_dirs = ['C:\\Users\\vagrant\\src\\master-env\\include']
blas_mkl_info:
    libraries = ['mkl_core_dll', 'mkl_intel_lp64_dll', 'mkl_intel_thread_dll']
    library_dirs = ['C:\\Users\\vagrant\\src\\master-env\\libs']
    define_macros = [('SCIPY_MKL_H', None)]
    include_dirs = ['C:\\Users\\vagrant\\src\\master-env\\include']
mkl_info:
    libraries = ['mkl_core_dll', 'mkl_intel_lp64_dll', 'mkl_intel_thread_dll']
    library_dirs = ['C:\\Users\\vagrant\\src\\master-env\\libs']
    define_macros = [('SCIPY_MKL_H', None)]
    include_dirs = ['C:\\Users\\vagrant\\src\\master-env\\include']

2 个回答

1

In [129]: import scipy.special as special    

In [133]: y = 8.21016005323e+158

In [134]: gama = -339.375260893

In [139]: special.errprint(True)
Out[139]: 0

In [140]: special.lambertw(y) + gama
Out[140]: (20.652375422199896+0j)

使用scipy版本0.14.0:

In [130]: import scipy

In [131]: scipy.__version__
Out[132]: '0.14.0.dev-371b4ff'

In [146]: scipy.show_config()
umfpack_info:
  NOT AVAILABLE
atlas_threads_info:
    libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/lib/atlas-base/atlas', '/usr/lib/atlas-base']
    define_macros = [('ATLAS_INFO', '"\\"3.8.4\\""')]
    language = f77
    include_dirs = ['/usr/include/atlas']
blas_opt_info:
    libraries = ['ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/lib/atlas-base']
    define_macros = [('ATLAS_INFO', '"\\"3.8.4\\""')]
    language = c
    include_dirs = ['/usr/include/atlas']
atlas_blas_threads_info:
    libraries = ['ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/lib/atlas-base']
    define_macros = [('ATLAS_INFO', '"\\"3.8.4\\""')]
    language = c
    include_dirs = ['/usr/include/atlas']
openblas_info:
  NOT AVAILABLE
lapack_opt_info:
    libraries = ['lapack', 'ptf77blas', 'ptcblas', 'atlas']
    library_dirs = ['/usr/lib/atlas-base/atlas', '/usr/lib/atlas-base']
    define_macros = [('ATLAS_INFO', '"\\"3.8.4\\""')]
    language = f77
    include_dirs = ['/usr/include/atlas']
lapack_mkl_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
mkl_info:
  NOT AVAILABLE
4

lambertw的代码中,有一个循环。显然,当输入一个很大的数时,它没有收敛。(正如@unutbu的回答所示,是否收敛似乎还跟你的配置有关。)

这里有一个替代方案,适用于最大浮点值范围内的(标量)正实数:

import numpy as np
from scipy.optimize import fsolve


def lw(x):
    """Lambert W function, for real x >= 0."""

    def func(w, x):
        return np.log(x) - np.log(w) - w

    if x == 0:
        return 0
    if x > 2.5:
        lnx = np.log(x)
        w0 = lnx - np.log(lnx)
    elif x > 0.25:
        w0 = 0.8 * np.log(x + 1)
    else:
        w0 = x * (1.0 - x)

    return fsolve(func, w0, args=(x,))[0]

例如:

In [79]: lw(8.21016005323e+158)
Out[79]: 360.02763631519991

In [80]: np.finfo(1.0).max
Out[80]: 1.7976931348623157e+308

In [81]: lw(np.finfo(1.0).max)
Out[81]: 703.22703310477016

这是我的配置:

In [87]: scipy.show_config()
atlas_threads_info:
  NOT AVAILABLE
blas_opt_info:
    extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
    extra_compile_args = ['-msse3', '-I/System/Library/Frameworks/vecLib.framework/Headers']
    define_macros = [('NO_ATLAS_INFO', 3)]
atlas_blas_threads_info:
  NOT AVAILABLE
openblas_info:
  NOT AVAILABLE
lapack_opt_info:
    extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
    extra_compile_args = ['-msse3']
    define_macros = [('NO_ATLAS_INFO', 3)]
atlas_info:
  NOT AVAILABLE
lapack_mkl_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
atlas_blas_info:
  NOT AVAILABLE
mkl_info:
  NOT AVAILABLE

撰写回答