【问题标题】:AttributeError: 'Mul' object has no attribute 'sqrt'AttributeError:“Mul”对象没有属性“sqrt”
【发布时间】:2019-12-09 03:35:28
【问题描述】:

我收到标题中所述的错误。完全错误:

MaxD = Cone*np.sqrt(SymsX/np.pi)*np.exp((-SymsX/(k*T))) #Define Maxwellian distribution function

AttributeError: 'Mul' object has no attribute 'sqrt'

代码如下:

from sympy.interactive import printing
printing.init_printing(use_latex = True)
import numpy as np
from sympy import Eq, dsolve, Function, Symbol, symbols
import sympy as sp

EpNaut = 8.854187E-12
u0 = 1.256E-6
k = 1/(4*np.pi*EpNaut)
NumGen = 1000 #How many solution points user wants to generate between 0 and maxen (Higher # the more accurate)
T = 1000 #Temperature in (K)
MaxEn = 7*T*k #Max energy in system
Cone = 2/((k*T)**(3/2)) #Constant infront of the Maxwellian distribution function

SymsX = sp.Symbol('SymsX')
MaxD = Function('MaxD')
PFunction = Function('PFunction')
MaxD = Cone*np.sqrt(SymsX/np.pi)*np.exp((-SymsX/(k*T))) #Define Maxwellian distribution function
PFunction = sp.integrate(MaxD) #Integrate function to get probability-error function

print(PFunction)

我还有一个问题。我有时会看到使用“from ... import ...”的示例。为什么是这样?不应该只导入整个库就足够了吗?是不是因为使用 import 命令实际上并没有导入整个库,而只是导入了最基本的函数?

【问题讨论】:

  • 我添加了一些相关的标签。问题源于在numpy 函数中使用sympy 对象。初学者不应该尝试混合sympynumpy;这不是一项微不足道的任务。我可以解释为什么它在这种情况下会产生错误,但现在说起来更简单 - 不要这样做!
  • (at)Hung Nguyen 在发布我的帖子之前我已经看过那个帖子,我可以看到它在那个例子中是如何工作的,但我不认为它是一个通用的解决方案,因为.. . @hpaulj 如果我希望使用仅在某些库中的运算符/常量怎么办?在某些时候,我需要在相同的定义中混合使用库。示例: sqrt() 运算符仅存在于 np 和 math 库中,定义函数和符号只能由 sp 库中的函数处理。
  • sympy可以做sqrt,以及所有的超验。
  • @hpaulj 好吧,我无法在文档中找到它们。我会仔细看看。我认为至少只要定义本身不使用正确的两个库,仍然可以为同一个脚本导入多个库?因为在某些时候,我希望在同一个脚本中同时使用符号数学(使用 sympy)和数值积分(使用 numpy),因为这两件事都没有。

标签: python numpy sympy


【解决方案1】:

isympy 会话中:

In [1]: import numpy as np                                                      

In [3]: SymsX = Symbol('SymsX')                                                 

In [5]: SymsX/np.pi                 # symbol * float                                                             
Out[5]: 0.318309886183791⋅SymsX

In [6]: SymsX/pi                    # symbol * symbol                            
Out[6]: 
SymsX
─────
  π  

In [7]: sqrt(SymsX/pi)             # sympy sqrt                           
Out[7]: 
  _______
╲╱ SymsX 
─────────
    √π   

In [8]: np.sqrt(SymsX/pi)          # numeric sqrt                                 
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
AttributeError: 'Mul' object has no attribute 'sqrt'

The above exception was the direct cause of the following exception:

TypeError                                 Traceback (most recent call last)
<ipython-input-8-27f855f6b3e2> in <module>
----> 1 np.sqrt(SymsX/pi)

TypeError: loop of ufunc does not support argument 0 of type Mul which has no callable sqrt method

np.sqrt 必须首先将其输入转换为 numpy 数组:

In [10]: np.array(SymsX/np.pi)                                                  
Out[10]: array(0.318309886183791*SymsX, dtype=object)

这是一个对象 dtype 数组,而不是普通的数字数组。给定这样一个数组, q numpy ufunc 尝试将操作委托给元素方法。例如(0.31*SymsX).sqrt()

乘法和加法确实适用于这个对象数组:

In [11]: 2*_                                                                    
Out[11]: 0.636619772367581⋅SymsX

In [12]: _ + __                                                                 
Out[12]: 0.954929658551372⋅SymsX

这些工作是因为sympy 对象具有正确的加法和乘法方法:

In [14]: Out[5].__add__                                                         
Out[14]: <bound method Expr.__add__ of 0.318309886183791*SymsX>

In [15]: Out[5]+2*Out[5]                                                        
Out[15]: 0.954929658551372⋅SymsX

===

sympy.lambdify 是同时使用sympynumpy 的最佳工具。查看它的文档。

在这种情况下,SymsX/pi 表达式可以转换为 numpy 表达式:

In [18]: lambdify(SymsX, Out[5],'numpy')                                        
Out[18]: <function _lambdifygenerated(SymsX)>

In [19]: _(23)            # evaluate with `SymsX=23`:                                                                  
Out[19]: 7.321127382227194

In [20]: 23/np.pi                                                               
Out[20]: 7.321127382227186

In [21]: np.sqrt(_19)        # np.sqrt now works on the number                            
Out[21]: 2.7057581899030065

====

sympy中的相同评价:

In [23]: expr = sqrt(SymsX/pi)                                                  

In [24]: expr                                                                   
Out[24]: 
  _______
╲╱ SymsX 
─────────
    √π   

In [25]: expr.subs(SymsX, 23)                                                   
Out[25]: 
√23
───
 √π

In [27]: _.evalf()                                                              
Out[27]: 2.70575818990300

【讨论】:

    【解决方案2】:

    在新的isympy 会话中:

    These commands were executed:
    >>> from __future__ import division
    >>> from sympy import *
    >>> x, y, z, t = symbols('x y z t')
    >>> k, m, n = symbols('k m n', integer=True)
    >>> f, g, h = symbols('f g h', cls=Function)
    >>> init_printing()
    
    Documentation can be found at https://docs.sympy.org/1.4/
    
    
    In [1]: EpNaut = 8.854187E-12 
       ...: u0 = 1.256E-6 
       ...: k = 1/(4*pi*EpNaut) 
       ...: NumGen = 1000  
       ...: T = 1000  
       ...: MaxEn = 7*T*k  
       ...: Cone = 2/((k*T)**(3/2)) 
       ...:  
       ...: SymsX = Symbol('SymsX') 
       ...: MaxD = Function('MaxD') 
       ...: PFunction = Function('PFunction') 
       ...: MaxD = Cone*sqrt(SymsX/pi)*exp((-SymsX/(k*T))) #Define Maxwellian distri
       ...: bution function 
       ...: PFunction = integrate(MaxD) #Integrate function to get probability-error
       ...:  function 
       ...:                                                                         
    

    结果:

    In [2]: PFunction                                                               
    Out[2]: 
                              ⎛                     _______  -3.5416748e-14⋅π⋅Syms
                          1.0 ⎜  28235229276273.5⋅╲╱ SymsX ⋅ℯ                     
    1.33303949775482e-20⋅π   ⋅⎜- ─────────────────────────────────────────────────
                              ⎝                          π                        
    
    X                           ⎛                         _______⎞⎞
        7.50165318945357e+19⋅erf⎝1.88193379267178e-7⋅√π⋅╲╱ SymsX ⎠⎟
    ─ + ──────────────────────────────────────────────────────────⎟
                                    π                             ⎠
    
    In [3]: MaxD                                                                    
    Out[3]: 
                          1.0   _______  -3.5416748e-14⋅π⋅SymsX
    1.33303949775482e-20⋅π   ⋅╲╱ SymsX ⋅ℯ                      
    

    SymsX 仍然是一个符号,所以这些是sympy 表达式,而不是数字。

    【讨论】:

      猜你喜欢
      • 2020-03-01
      • 2019-07-07
      • 1970-01-01
      • 2012-12-01
      • 2021-04-19
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      • 2018-08-28
      相关资源
      最近更新 更多