【问题标题】:Plot pairs of solutions to non-linear equation绘制非线性方程的解对
【发布时间】:2019-09-10 12:32:16
【问题描述】:

我尝试使用以下代码绘制对 (x,y),它们是方程 y^2 + y = x^3 + y(x^2) 的解:

import numpy as np
y = np.arange(0,12,.01)
x = np.arange(0,18,.01)
for i in enumerate(y):
    for j in enumerate(x):
        if (i**2)+i == j**3 + i*(j**2):
            plot(i,j)

但是,我收到以下错误: "TypeError: ** 或 pow() 不支持的操作数类型:'tuple' 和 'int'"

任何人都可以帮助我弄清楚如何绘制解决方案?

我还有一个问题:是否可以将每对解决方案存储在一个变量中,以便我们将来使用特定的解决方案对?

【问题讨论】:

    标签: python numpy matplotlib


    【解决方案1】:

    enumerate 产生(index, value) 元组,您可以使用解包在循环头中分别获取每个:

    for i_ind, i in enumerate(y):
        for j_ind, j in enumerate(x):
    

    【讨论】:

    • 感谢@MrGeek 的回复。是否需要将方程中的 i 和 j 替换为 i_val 和 j_val?
    • @shirinelahi 您可以将变量重命名为您想要的任何名称,重要的是顺序是(index, value)
    【解决方案2】:

    我建议您修改公式并改为绘制 LHS 和 RHS 之间的平方差:

    x = np.linspace(-1, 1, 100)
    y = np.linspace(-1, 1, 100)
    X, Y = np.meshgrid(x, y)
    
    def F(p):
        x, y = p
        v = y**2 + y - x**3 - y * (x**2)
        return v**2
    
    Z = F((X, Y))
    plt.contourf(X, Y, Z)
    plt.colorbar()
    idx = np.where(np.abs(Z) < 1e-4)
    plt.scatter(X[idx], Y[idx], marker='+', color='w')
    

    您还可以使用scipy.optimize.fmin(F, [1, 1]) 得到F=0 的精确解,其中[1, 1] 是您的初始猜测。在这种情况下,不同的初始猜测会导致不同的解。

    【讨论】:

    • 非常感谢@CT Zhu。这就是我一直在寻找的解决方案。
    【解决方案3】:

    虽然另一个答案描述了阻止抛出异常所需的机械转换,但它不会在您的情节中得到任何点。 Numpy 是一个数值库,而您想要/需要解方程。

    numpy.arange(0, 12, 0.01) 生成一个 有限 系列数字,从 0 开始,以 0.01 递增,直到达到 12。您给出上面的一个等式,该等式主要被翻译成 Python 代码,并在这些有限上对其进行评估一系列数字,并要求它绘制两个表达式计算为相同数字的值。 Python 中的浮点数是 64-bit floats,因此这个相等性被检查到大约 15 个十进制数字,这对于您的数字基本上不会发生。

    而不是做你想做的事,你想使用像Sympy 这样实际上会帮助你的东西。开始我们做:

    from sympy import symbols, solveset, simplify, lambdify
    
    x, y = symbols('x y')
    
    eq1 = y**2 + y
    eq2 = x**3 + x*y**2
    
    ss = solveset(eq1 - eq2, y)
    

    它命名一对符号,将它们放入一些方程中,solves 用于何时eq1 == eq2(等效于当它们的差为零时)。

    接下来你要绘制这些解,在这种情况下可以这样做:

    import numpy as np
    import matplotlib.pyplot as plt
    
    xx = np.linspace(-5, 4, 101)
    for eq in ss:
        fn = lambdify(x, eq)
        yy = fn(xx)
        # hide complex solutions
        yy[~np.isreal(yy)] = np.nan
        plt.plot(xx, np.real(yy), label=simplify(eq))
    
    plt.legend()
    

    首先引入 numpy 和 matplotlib,然后在 x 轴上采样我们要评估函数的点,然后循环解决方案,将它们转换为 Python 函数,我们可以评估以获得数字答案,接下来我们评估这在我们的采样点上,丢弃复杂的解决方案,并绘制结果。

    这给出了:

    x = -4.5 周围的差距是由于此时的采样稀疏。我们可以通过在x=-4.5, y=10 评估我们的方程来检查,两个方程我得到 ~110

    【讨论】:

    • 非常感谢 Sam 的全面解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    相关资源
    最近更新 更多