You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python 3.10+NumPy求多项式指定Y值对应的所有实X值?

求解多项式对应指定Y值的实X值问题

问题描述

在Python 3.10中,给定降序排列系数的多项式,计算指定Y值对应的所有实X值,结果以list形式返回。使用numpy的roots()函数时未得到正确结果,当前运行结果为[-2.0, 0.0],与预期不符。

原代码

import numpy as np
import matplotlib.pyplot as plt

def main():
    coeffs = np.array([1, 2, 2])
    y = 1.5

    polyDataX = np.linspace(-2, 0)
    polyDataY = np.empty(shape = len(polyDataX), dtype = float)

    for i in range(len(polyDataX)):
        polyDataY[i] = coeffs[0] * pow(polyDataX[i], 2) + coeffs[1] * polyDataX[i] + coeffs[2]

    coeffs[-1] -= y
    x = np.roots(coeffs).tolist()

    plt.axhline(y, color = "orange")
    plt.plot(polyDataX, polyDataY, color = "blue")
    plt.title("X = " + str(x))
    plt.show()
    plt.close()
    plt.clf()

if (__name__ == "__main__"):
    main()

错误原因分析

你得到[-2.0, 0.0]的结果,说明实际求解的是多项式x²+2x=0(对应Y=2的情况),而非目标的x²+2x+0.5=0。可能的问题点:

  • 代码运行时y的值被误设为2,而非1.5;
  • 直接修改原coeffs数组时出现意外覆盖(不过在你的代码逻辑中,原数组已完成绘图数据计算,修改不会影响这一步)。

此外,numpy.roots()会返回所有根(包括复数根),若多项式无实根,需要过滤掉虚部不为0的结果。

正确实现方法

步骤说明

  1. 构造目标多项式:将原多项式转换为P(x) - y = 0,即仅需将原系数的最后一项(常数项)减去y,注意要创建数组副本避免修改原数据;
  2. 求解所有根:使用numpy.roots()获取多项式的所有根;
  3. 过滤实根:判断根的虚部是否趋近于0(考虑浮点精度误差),提取实部作为结果;
  4. 返回list形式结果:将过滤后的实根转换为Python列表。

修正后的代码

import numpy as np
import matplotlib.pyplot as plt

def find_real_x(coeffs, y):
    # 创建系数副本,避免修改原数据
    target_coeffs = coeffs.copy()
    # 构造P(x)-y=0的多项式系数
    target_coeffs[-1] -= y
    # 求解所有根
    all_roots = np.roots(target_coeffs)
    # 过滤实根:虚部绝对值小于1e-9视为实根
    real_roots = [root.real for root in all_roots if np.abs(root.imag) < 1e-9]
    return real_roots

def main():
    coeffs = np.array([1, 2, 2], dtype=np.float64)
    y = 1.5

    # 计算绘图数据,用np.polyval简化多项式求值
    polyDataX = np.linspace(-2, 0, 100)
    polyDataY = np.polyval(coeffs, polyDataX)

    # 获取实根
    real_x = find_real_x(coeffs, y)

    # 绘图展示
    plt.axhline(y, color="orange", label=f"Y={y}")
    plt.plot(polyDataX, polyDataY, color="blue", label="Polynomial")
    # 标记实根位置
    for x_val in real_x:
        plt.scatter(x_val, y, color="red", zorder=5)
    plt.title(f"Real X values: {[round(x,4) for x in real_x]}")
    plt.legend()
    plt.show()

if __name__ == "__main__":
    main()

代码优化点

  • 使用np.polyval()简化多项式求值,替代手动循环,更高效且不易出错;
  • 创建系数副本,避免修改原数组导致的潜在问题;
  • 添加浮点精度判断,过滤复数根,确保结果仅包含实根;
  • 绘图时标记实根位置,直观验证结果正确性。

运行结果

修正后的代码会返回实根列表[-1.7071067811865475, -0.2928932188134524],对应抛物线与Y=1.5的两个交点,与预期一致。

内容的提问来源于stack exchange,提问作者Runsva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 00:59:50