【问题标题】:Error using 'exp' in sympy -TypeError and Attribute Error is displayed在 sympy -TypeError 中使用“exp”时出错,并显示属性错误
【发布时间】:2019-05-19 17:01:52
【问题描述】:

我想在 Python3 上使用 sympy 求解微分方程。我的方程式相对简单,有两个变量。但是,该等式具有 log、power 和 exp 运算符。无论我使用 np.exp 还是 sym.exp,它都会给我以下两个错误之一:

TypeError: 'module' object is not callable

AttributeError: 'Mul' object has no attribute 'log'
AttributeError: 'Mul' object has no attribute 'exp'

我正在分别导入 numpy 和 sympy。我不确定这两个库是否冲突。

import math
import sympy as sym
from sympy import symbols, diff, exp, log, power
from sympy import *

data = [3, 33, 146, 227, 342, 351, 353, 444, 556, 571, 709, 759, 836, 860, 968, 1056, 1726, 1846, 1872, 1986, 2311, 2366, 2608, 2676, 3098, 3278, 3288, 4434, 5034, 5049, 5085, 5089, 5089, 5097, 5324, 5389,5565, 5623, 6080, 6380, 6477, 6740, 7192, 7447, 7644, 7837, 7843, 7922, 8738, 10089, 10237, 10258, 10491, 10625, 10982, 11175, 11411, 11442, 11811, 12559, 12559, 12791, 13121, 13486, 14708, 15251, 15261, 15277, 15806, 16185, 16229, 16358, 17168, 17458, 17758, 18287, 18568, 18728, 19556, 20567, 21012, 21308, 23063, 24127, 25910, 26770, 27753, 28460, 28493, 29361, 30085, 32408, 35338, 36799, 37642, 37654, 37915, 39715, 40580, 42015, 42045, 42188, 42296, 42296, 45406, 46653, 47596, 48296, 49171, 49416, 50145, 52042, 52489, 52875, 53321, 53443, 54433, 55381, 56463, 56485, 56560, 57042, 62551, 62651, 62661, 63732, 64103, 64893, 71043, 74364, 75409, 76057, 81542, 82702, 84566, 88682]
n = len(data)
tn = data[n-1]


b, c = sym.symbols('b c', real=True)

f = -(-n +sum(np.log(b*c*np.power(data,(c-1))*exp(-b*np.power(data,c)))))

diff(f,b)
diff(f,c)

期望导出方程“f”关于参数“b”和“c”的偏导数

这与What causes this error (AttributeError: 'Mul' object has no attribute 'cos') in Python? 不同,原因不是命名空间问题

【问题讨论】:

  • 问题是您尝试将 numpy log 和 exp 应用于 sympy 对象列表。这些函数旨在处理数字数组。不要在没有清楚了解它们的工作原理的情况下将 numpy 和 sympy 混为一谈。
  • @DeveshKumarSingh 不,我在发布之前通读了该帖子。这是一个命名空间问题,因为 from sympy import * from numpy import *
  • @hpaulj 我尝试使用 sym.log 和 sym.power 但这并没有解决问题。
  • np.log 是这里的罪魁祸首,试着玩弄它,看看你能不能让它工作

标签: python python-3.x numpy sympy


【解决方案1】:

isympy 会话中(类似于您的导入),加上np 导入:

In [12]: data = [1,2,3,4,5]                                                  

In [13]: np.power(data,c)                                                    
Out[13]: array([1, 2**c, 3**c, 4**c, 5**c], dtype=object)

In [14]: b*c*np.power(data,c)                                                
Out[14]: array([b*c, 2**c*b*c, 3**c*b*c, 4**c*b*c, 5**c*b*c], dtype=object)

到目前为止,这些工作。当numpy 函数和运算符遇到对象 dtype 数组(非数字数组)时,它们会尝试应用对象的相应运算符或方法。 bc 作为 symbols 回复 ***

np.log 应用于对象数组失败并显示您的错误消息。数组的元素一个 sympy Mul 对象:

In [17]: type(Out[14][0])                                                    
Out[17]: sympy.core.mul.Mul
In [18]: Out[14][0].log()                                                    
---------------------------------------------------------------------------
AttributeError: 'Mul' object has no attribute 'log'

np.exp 也一样。

math.log 需要一个数字,因此它也不适用于数组或 sympy 对象。

sympy.log(Out[14][0]) 有效 - 参数是 sympy Mul。但它不适用于 Out[14] 这是一个 numpy 数组。

===

我知道numpysympy 好很多。但我能够让这个计算序列起作用:

In [24]: [d**c for d in data]     # list comprehension                                                
Out[24]: 
⎡    c   c   c   c⎤
⎣1, 2 , 3 , 4 , 5 ⎦

In [25]: [b*c*num**c for num in data]                                        
Out[25]: 
⎡      c       c       c       c    ⎤
⎣b⋅c, 2 ⋅b⋅c, 3 ⋅b⋅c, 4 ⋅b⋅c, 5 ⋅b⋅c⎦

In [26]: [log(b*c*num**c) for num in data]                                   
Out[26]: 
⎡             ⎛ c    ⎞     ⎛ c    ⎞     ⎛ c    ⎞     ⎛ c    ⎞⎤
⎣log(b⋅c), log⎝2 ⋅b⋅c⎠, log⎝3 ⋅b⋅c⎠, log⎝4 ⋅b⋅c⎠, log⎝5 ⋅b⋅c⎠⎦

In [27]: sum([log(b*c*num**c) for num in data])                              
Out[27]: 
              ⎛ c    ⎞      ⎛ c    ⎞      ⎛ c    ⎞      ⎛ c    ⎞
log(b⋅c) + log⎝2 ⋅b⋅c⎠ + log⎝3 ⋅b⋅c⎠ + log⎝4 ⋅b⋅c⎠ + log⎝5 ⋅b⋅c⎠

sympy.sum 需要一个可迭代的,此列表符合条件。

现在我可以做sympy.diff

In [29]: diff(sum([log(b*c*num**c) for num in data]),b)                      
Out[29]: 
5
─
b

In [30]: diff(sum([log(b*c*num**c) for num in data]),c)                      
Out[30]: 
     -c ⎛ c               c  ⎞    -c ⎛ c               c  ⎞    -c ⎛ c      
1   5  ⋅⎝5 ⋅b⋅c⋅log(5) + 5 ⋅b⎠   4  ⋅⎝4 ⋅b⋅c⋅log(4) + 4 ⋅b⎠   3  ⋅⎝3 ⋅b⋅c⋅l
─ + ────────────────────────── + ────────────────────────── + ─────────────
c              b⋅c                          b⋅c                          b⋅

         c  ⎞    -c ⎛ c               c  ⎞
og(3) + 3 ⋅b⎠   2  ⋅⎝2 ⋅b⋅c⋅log(2) + 2 ⋅b⎠
───────────── + ──────────────────────────
c                          b⋅c    

[log(item) for item in Out[14]] 产生与Out[26] 相同的输出。 Out[14] 只是与 Out[25] 列表等效的对象数组。

【讨论】:

  • sympy.log 有效,但是当您将它与数组的幂相结合时,它会返回您在上面报告的错误。是否有另一种方法来计算与 sympy 兼容的数组的功率?
  • sympy.log 设计用于sympy 对象,但不适用于numpy 数组。为什么要这样做?
  • 感谢您帮助我解决这个问题。使用列表推导解决了这个问题。这是我修改后的有效代码: f = -(-n +sum([sym.log(bc*(num**(c-1))*sym.exp(-b*(num*c))) for num in data]))
【解决方案2】:

根据@hpaulj 的建议,我能够通过使用列表理解来解决这个问题。工作代码如下:

f = -(-n +sum([sym.log(b*c*(num**(c-1))*sym.exp(-b*(num**c))) for num in data]))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-17
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 2021-07-01
    相关资源
    最近更新 更多