如何在 python 中将浮点数作为字符串传递给 mpmath?

How to pass a float as string to mpmath in python?

如果我想将浮点数传递给 mpmath.mpf 并使用 mp.findroot 找到根,我会遇到一些麻烦。

这个问题延续了上一个问题的故事:

import sympy
omega = sympy.symbols('omega')
from sympy import I 
import mpmath as mp
import numpy as np

# Definition of simplified function
def function(omega):
    return sympy.Poly((-1.16*omega**4), omega)

# This function does not work
def doesntwork(omega):
    return (mp.mpf(str(np.real(sympy.lambdify( (I),function(omega).coeffs()[0])(1j)))) * omega ** 4)

# This function does work, but I need to handover the value due to its not constant
def doeswork(omega):
    return (mp.mpf('-1.16') * omega ** 4)

#print mp.findroot(doesntwork, 1)   # error message
print mp.findroot(doeswork, 1)      # result is obtained

如果我用字符串输入系数,mp.findroot 命令会起作用,但如果我通过自动程序读取系数,它就不起作用。问题似乎是由 mpmath.mpf 的输入未被识别为字符串引起的。我需要这个自动程序,因为在这个简单的例子中系数不是常数。

函数不工作的错误消息是:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-44-7ed2fe96e32b> in <module>()
----> 1 print mp.findroot(doesntwork, 1)   # error message
      2 #print mp.findroot(doeswork, 1)      # result is obtained

C:\Anaconda\lib\site-packages\mpmath\calculus\optimization.pyc in findroot(ctx, f, x0, solver, tol, verbose, verify, **kwargs)
    926         # detect multidimensional functions
    927         try:
--> 928             fx = f(*x0)
    929             multidimensional = isinstance(fx, (list, tuple, ctx.matrix))
    930         except TypeError:

<ipython-input-40-f85df4161c52> in doesntwork(omega)
      1 # This function does not work
      2 def doesntwork(omega):
----> 3     return (mp.mpf(str(np.real(sympy.lambdify( (I),function(omega).coeffs()[0])(1j)))) * omega ** 4)
      4 
      5 # This function does work, but I need to handover the value due to its not constant

<ipython-input-39-fb50e638fea4> in function(omega)
      1 # Definition of simplified function
      2 def function(omega):
----> 3     return sympy.Poly((-1.16*omega**4), omega)

C:\Anaconda\lib\site-packages\sympy\polys\polytools.pyc in __new__(cls, rep, *gens, **args)
     71     def __new__(cls, rep, *gens, **args):
     72         """Create a new polynomial instance out of something useful. """
---> 73         opt = options.build_options(gens, args)
     74 
     75         if 'order' in opt:

C:\Anaconda\lib\site-packages\sympy\polys\polyoptions.pyc in build_options(gens, args)
    729 
    730     if len(args) != 1 or 'opt' not in args or gens:
--> 731         return Options(gens, args)
    732     else:
    733         return args['opt']

C:\Anaconda\lib\site-packages\sympy\polys\polyoptions.pyc in __init__(self, gens, args, flags, strict)
    152                     self[option] = cls.preprocess(value)
    153 
--> 154         preprocess_options(args)
    155 
    156         for key, value in dict(defaults).items():

C:\Anaconda\lib\site-packages\sympy\polys\polyoptions.pyc in preprocess_options(args)
    150 
    151                 if value is not None:
--> 152                     self[option] = cls.preprocess(value)
    153 
    154         preprocess_options(args)

C:\Anaconda\lib\site-packages\sympy\polys\polyoptions.pyc in preprocess(cls, gens)
    290         elif has_dups(gens):
    291             raise GeneratorsError("duplicated generators: %s" % str(gens))
--> 292         elif any(gen.is_commutative is False for gen in gens):
    293             raise GeneratorsError("non-commutative generators: %s" % str(gens))
    294 

C:\Anaconda\lib\site-packages\sympy\polys\polyoptions.pyc in <genexpr>((gen,))
    290         elif has_dups(gens):
    291             raise GeneratorsError("duplicated generators: %s" % str(gens))
--> 292         elif any(gen.is_commutative is False for gen in gens):
    293             raise GeneratorsError("non-commutative generators: %s" % str(gens))
    294 

AttributeError: 'mpf' object has no attribute 'is_commutative'

感谢您的帮助!

我解决了这个问题。显然,如果之前将系数存储在一个变量中就不一样了。

coefficient = str(np.real(sympy.lambdify( (I),function(omega).coeffs()[0])(1j)))
def doesntwork(omega):
    return (mp.mpf(coefficient) * omega ** 4)

print mp.findroot(doesntwork, 1) 

输出

0.00267117593442144