问题
I am receiving the error stated in the title. Full error:
MaxD = Cone*np.sqrt(SymsX/np.pi)*np.exp((-SymsX/(k*T))) #Define Maxwellian distribution function
AttributeError: 'Mul' object has no attribute 'sqrt'
Here is the code:
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)
I also have an additional question. I sometimes see examples use "from ... import ...". Why is this? Shouldn't just importing the entire library be enough? Is it because using the import command doesn't actually import the entire library but really just the most basic functions?
回答1:
In an isympy session:
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 has to first convert its input into a numpy array:
In [10]: np.array(SymsX/np.pi)
Out[10]: array(0.318309886183791*SymsX, dtype=object)
This is an object dtype array, not a normal numeric one. Given such an array, q numpy ufunc tries to delegate the action to a element method. e.g. (0.31*SymsX).sqrt()
Multiply and addition do work with this object array:
In [11]: 2*_
Out[11]: 0.636619772367581⋅SymsX
In [12]: _ + __
Out[12]: 0.954929658551372⋅SymsX
These work because the sympy object has the right add and multiply methods:
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
===
The sympy.lambdify is the best tool for using sympy and numpy together. Look up its docs.
In this case the SymsX/pi expression can be converted into a numpy expression with:
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
====
The same evaluation in 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:
In a fresh isympy session:
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
...:
The result:
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 is still a symbol, so these are sympy expressions, not numbers.
来源:https://stackoverflow.com/questions/59242194/attributeerror-mul-object-has-no-attribute-sqrt