SOLVE: AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_independent'

SOLVE: AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_independent'

我对 python 很陌生,我一直在尝试用几种不同的方式来绘制它。如果我尝试使用 np.vectorize,它会崩溃。

所以我写了这段代码,它给了我标题中的错误:

import math
import numpy as np
from scipy import optimize
from scipy import interpolate
from scipy import integrate
import matplotlib.pyplot as plt
from sympy import Symbol
from sympy.solvers import solve
import sympy


fig = plt.figure(2, figsize=(10, 7))
ax = fig.gca(projection='3d')
x = np.linspace(-1, 1, num=20)
y = np.linspace(-1, 1, num=20)
X, Y = np.meshgrid(x, y)

#we define a function where we use sympy.solvers.solve and return both values of z
def surfacez(x, y):
    z = Symbol('z')
    surface = solve(x + 2 * y + z + math.e ** (2 * z), z)
    return surface


Z = surfacez(X,Y)


#we plot for both values of z
surf = ax.plot_wireframe(X, Y, Z, linewidth=1, antialiased=False, color='b')
plt.xlabel('x')
plt.ylabel('y')
ax.set_zlabel('z')
plt.title('Quadratic surface')


完整追溯:

回溯(最近调用最后):

  File "C:\Users\natty\Desktop\LU\MATB21\crash.py", line 39, in <module>
    Z = surfacez(X,Y)

  File "C:\Users\natty\Desktop\LU\MATB21\crash.py", line 32, in surfacez
    surface = solve(x + 2 * y + z + math.e ** (2 * z), z)

  File "C:\Users\natty\AppData\Local\Programs\Spyder\pkgs\sympy\solvers\solvers.py", line 1096, in solve
    solution = _solve_system(f, symbols, **flags)

  File "C:\Users\natty\AppData\Local\Programs\Spyder\pkgs\sympy\solvers\solvers.py", line 1730, in _solve_system
    i, d = _invert(g, *symbols)

  File "C:\Users\natty\AppData\Local\Programs\Spyder\pkgs\sympy\solvers\solvers.py", line 3109, in _invert
    indep, dep = lhs.as_independent(*symbols)

AttributeError: 'ImmutableDenseNDimArray' object has no attribute 'as_independent'

我不知道这个错误是什么意思,你能建议一种修复方法或这个错误的根源吗?

In [66]: z
Out[66]: z
In [67]: X,Y=np.meshgrid([1,2,3],[1,2])
In [68]: X
Out[68]: 
array([[1, 2, 3],
       [1, 2, 3]])
In [69]: Y
Out[69]: 
array([[1, 1, 1],
       [2, 2, 2]])
In [71]: expr = X +2 * Y + z + E  ** (2*z)
In [72]: expr
Out[72]: 
array([[z + exp(2*z) + 3, z + exp(2*z) + 4, z + exp(2*z) + 5],
       [z + exp(2*z) + 5, z + exp(2*z) + 6, z + exp(2*z) + 7]],
      dtype=object)

看起来 solve 已将此 numpy 数组转换为 sympy 数组:

In [74]: Array(expr)
Out[74]: 
⎡     2⋅z           2⋅z           2⋅z    ⎤
⎢z + ℯ    + 3  z + ℯ    + 4  z + ℯ    + 5⎥
⎢                                        ⎥
⎢     2⋅z           2⋅z           2⋅z    ⎥
⎣z + ℯ    + 5  z + ℯ    + 6  z + ℯ    + 7⎦
In [75]: type(_)
Out[75]: sympy.tensor.array.dense_ndim_array.ImmutableDenseNDimArray

我还没有探索 solve 太多,但显然这不是它可以处理的表达式系统之一。

对于标量值

In [80]: X,Y=1,2
In [83]: expr = X +2 * Y + z + E  ** (2*z)
In [84]: expr
Out[84]: 
     2⋅z    
z + ℯ    + 5
In [85]: solve(expr,z)
Out[85]: 
⎡      ⎛   -10⎞⎤
⎢     W⎝2⋅ℯ   ⎠⎥
⎢-5 - ─────────⎥
⎣         2    ⎦

和符号 xy:

In [86]: expr = x +2 * y + z + E  ** (2*z)
In [87]: expr
Out[87]: 
               2⋅z
x + 2⋅y + z + ℯ   
In [88]: solve(expr,z)
Out[88]: 
⎡            ⎛   -2⋅x - 4⋅y⎞⎤
⎢           W⎝2⋅ℯ          ⎠⎥
⎢-x - 2⋅y - ────────────────⎥
⎣                  2        ⎦
In [89]: sol=_[0]
In [90]: sol.subs({x:1, y:2})
Out[90]: 
      ⎛   -10⎞
     W⎝2⋅ℯ   ⎠
-5 - ─────────
         2    

我们可以尝试从中创建一个 python 函数:

In [91]: f = lambdify((x,y),sol)
In [92]: help(f)

Help on function _lambdifygenerated:

_lambdifygenerated(x, y)
    Created with lambdify. Signature:
    
    func(x, y)
    
    Expression:
    
    -x - 2*y - LambertW(2*exp(-2*x - 4*y))/2
    
    Source code:
    
    def _lambdifygenerated(x, y):
        return (-x - 2*y - 1/2*lambertw(2*exp(-2*x - 4*y)))

我不确定 LambertW。显然,股票 python/numpy 中没有这样的东西。 scipy也许。

好的,scipy 确实有:https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.lambertw.html

In [95]: from scipy.special import lambertw as lambertW
In [96]: f(1,2)
Out[96]: (-5.000045395808017+0j)

sympy's自己的数值解比较:

In [97]: sol.subs({x:1, y:2})
Out[97]: 
      ⎛   -10⎞
     W⎝2⋅ℯ   ⎠
-5 - ─────────
         2    
In [98]: N(sol.subs({x:1, y:2}))
Out[98]: -5.00004539580802

并且使用数组参数,lambdified 函数:

In [99]: X,Y=np.meshgrid([1,2,3],[1,2])
In [100]: f(X,Y)
Out[100]: 
array([[-3.00246655+0.j, -4.00033524+0.j, -5.0000454 +0.j],
       [-5.0000454 +0.j, -6.00000614+0.j, -7.00000083+0.j]])

sympy.lambdify 是在 numpy 函数中使用 sympy 表达式的最佳工具之一。它无法处理所有情况,因为翻译主要是词汇,没有深入理解 numpy。有过这样的案例。