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

如何在MySQL中实现numpy roots函数的多项式求根功能?

将numpy.roots三次求根逻辑迁移到MySQL的实现方案

首先明确你用numpy计算的多项式:numpy.roots([-2, 3, 0, -x])对应的是三次方程 -2t³ + 3t² - x = 0,等价于2t³ - 3t² + x = 0,你取的是返回数组中索引1的根(numpy返回的根按模长从小到大排序)。

直接在MySQL里复现numpy底层的特征值分解逻辑不现实,因为MySQL没有内置的矩阵运算和特征值计算能力,我们可以用三次方程解析解法模拟这个逻辑,或者用数值迭代法求解特定根,以下是具体实现思路:

方案1:基于卡尔丹公式的解析解法(适配所有实数x)

三次方程有成熟的解析解(卡尔丹公式+三角函数解法),我们可以根据判别式区分实根/复根场景,计算所有根后按模长排序,取索引1的根。

步骤1:判别式划分场景

对于转换后的标准三次方程z³ - 0.75z + (x-0.5)/2 = 0,判别式:

delta = (x*x - x)/16.0
  • 当delta >= 0:方程有1个实根+2个共轭复根
  • 当delta < 0:方程有3个不同实根(对应0 < x < 1)

步骤2:MySQL自定义函数实现

以下是适配MySQL 8.0+的自定义函数(用JSON数组兼容低版本),复根场景下MySQL无法直接返回复数,这里返回复根的实部,若需完整复根可拆分返回实部/虚部两列:

DELIMITER //
CREATE FUNCTION calc_numpy_root(x_val DOUBLE) RETURNS DOUBLE
DETERMINISTIC
BEGIN
    DECLARE delta, q_val, p_val DOUBLE;
    DECLARE a, b, z1, z2_real DOUBLE;
    DECLARE t1, t2, t3 DOUBLE;
    DECLARE roots JSON;

    SET p_val = -0.75;
    SET q_val = (x_val - 0.5)/2.0;
    SET delta = (q_val/2.0)*(q_val/2.0) + POWER(p_val/3.0, 3);

    IF delta >= 0 THEN
        -- 1实根+2复根场景
        SET a = POWER( (-q_val/2.0) + SQRT(delta), 1.0/3.0 );
        SET b = POWER( (-q_val/2.0) - SQRT(delta), 1.0/3.0 );
        SET z1 = a + b;
        SET t1 = z1 + 0.5; -- 实根
        SET z2_real = -0.5*(a + b);
        SET t2 = z2_real + 0.5; -- 复根实部

        -- 按模长排序,取索引1的根(numpy 0-based)
        IF ABS(t1) < SQRT(POWER(t2,2) + POWER( (SQRT(3)/2)*(a-b), 2 )) THEN
            RETURN t2;
        ELSE
            RETURN t1;
        END IF;
    ELSE
        -- 3实根场景(0<x<1),用三角函数解法
        DECLARE theta DOUBLE;
        SET theta = ACOS(1 - 2*x_val)/3.0;

        SET t1 = COS(theta) + 0.5;
        SET t2 = COS(theta + 2*PI()/3) + 0.5;
        SET t3 = COS(theta + 4*PI()/3) + 0.5;

        -- 将根存入JSON数组,按模长排序后取第二个元素(numpy索引1)
        SET roots = JSON_ARRAY(t1, t2, t3);
        -- 手动实现按绝对值排序
        SET roots = JSON_ARRAY(
            IF(ABS(JSON_EXTRACT(roots, '$[0]')) <= ABS(JSON_EXTRACT(roots, '$[1]')) AND ABS(JSON_EXTRACT(roots, '$[0]')) <= ABS(JSON_EXTRACT(roots, '$[2]')), JSON_EXTRACT(roots, '$[0]'),
               IF(ABS(JSON_EXTRACT(roots, '$[1]')) <= ABS(JSON_EXTRACT(roots, '$[2]')), JSON_EXTRACT(roots, '$[1]'), JSON_EXTRACT(roots, '$[2]'))),
            IF( (ABS(JSON_EXTRACT(roots, '$[0]')) BETWEEN ABS(JSON_EXTRACT(roots, '$[1]')) AND ABS(JSON_EXTRACT(roots, '$[2]'))) OR (ABS(JSON_EXTRACT(roots, '$[0]')) BETWEEN ABS(JSON_EXTRACT(roots, '$[2]')) AND ABS(JSON_EXTRACT(roots, '$[1]'))), JSON_EXTRACT(roots, '$[0]'),
               IF( (ABS(JSON_EXTRACT(roots, '$[1]')) BETWEEN ABS(JSON_EXTRACT(roots, '$[0]')) AND ABS(JSON_EXTRACT(roots, '$[2]'))) OR (ABS(JSON_EXTRACT(roots, '$[1]')) BETWEEN ABS(JSON_EXTRACT(roots, '$[2]')) AND ABS(JSON_EXTRACT(roots, '$[0]'))), JSON_EXTRACT(roots, '$[1]'), JSON_EXTRACT(roots, '$[2]'))),
            IF(ABS(JSON_EXTRACT(roots, '$[0]')) >= ABS(JSON_EXTRACT(roots, '$[1]')) AND ABS(JSON_EXTRACT(roots, '$[0]')) >= ABS(JSON_EXTRACT(roots, '$[2]')), JSON_EXTRACT(roots, '$[0]'),
               IF(ABS(JSON_EXTRACT(roots, '$[1]')) >= ABS(JSON_EXTRACT(roots, '$[2]')), JSON_EXTRACT(roots, '$[1]'), JSON_EXTRACT(roots, '$[2]')))
        );
        RETURN JSON_EXTRACT(roots, '$[1]'); -- 对应numpy的索引1
    END IF;
END //
DELIMITER ;

步骤3:调用函数查询

直接在SQL中调用函数即可得到对应结果:

SELECT x, calc_numpy_root(x) AS y FROM your_table_name;

方案2:牛顿迭代法(仅适用于实根场景)

如果你的x取值范围是0 < x < 1(此时三个根都是实根),可以针对索引1的根所在区间用牛顿迭代法快速求解,效率更高:

比如当0 < x < 1时,索引1的根通常在0~1区间,初始值设为0.5,迭代3-5次即可达到精度要求:

DELIMITER //
CREATE FUNCTION calc_root_newton(x_val DOUBLE) RETURNS DOUBLE
DETERMINISTIC
BEGIN
    DECLARE t, f, f_prime DOUBLE;
    SET t = 0.5; -- 初始值
    -- 迭代5次足够收敛
    SET @iter = 0;
    WHILE @iter < 5 DO
        SET f = 2*POWER(t,3) - 3*POWER(t,2) + x_val;
        SET f_prime = 6*POWER(t,2) - 6*t;
        IF f_prime = 0 THEN SET t = t + 0.0001; END IF; -- 避免除以0
        SET t = t - f/f_prime;
        SET @iter = @iter +1;
    END WHILE;
    RETURN t;
END //
DELIMITER ;

注意事项

  1. 若你的x会产生复根,MySQL无法直接存储复数类型,建议拆分返回实部和虚部两列;
  2. 自定义函数的精度可通过调整迭代次数或解析解中的计算步骤优化;
  3. 低版本MySQL(<8.0)不支持数组/JSON排序,需用临时表或嵌套条件判断实现根的排序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:12:33