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

如何让scipy的approx_fprime返回数组而非标量以计算偏导数矩阵?

问题

我正在尝试让approx_fprime返回多值(数组)而非仅标量,场景为方程组的误差传播:

from scipy.optimize import fsolve, approx_fprime
import numpy as np

def pipeline2(inp):
    sol1,sol1A,sol1B,sol1AB=inp
    def equations(initial):
            x,y,k1,k=initial
            sol1_equation=((k*k1)/(1+k1))-sol1
            sol1A_equation=((k*k1*x**2)/(1+k1*x))-sol1A
            sol1B_equation=((k*k1*y**2)/(1+k1*y))-sol1B
            sol1AB_equation=((k*k1*x**2*y**2)/(1+k1*x*y))-sol1AB
            return(sol1_equation,sol1A_equation,sol1B_equation,sol1AB_equation)
    val1,val2,val3,val4=fsolve(equations,(7,30,0.02,500))
    return np.array([val1,val2,val3,val4])

我手动实现了偏导数矩阵的计算:

h=1e-10
differential=np.array([(pipeline2(sol1_value+h,sol1A_value,sol1B_value,sol1AB_value)-pipeline2(sol1_value,sol1A_value,sol1B_value,sol1AB_value))/h,
                       (pipeline2(sol1_value,sol1A_value+h,sol1B_value,sol1AB_value)-pipeline2(sol1_value,sol1A_value,sol1B_value,sol1AB_value))/h,
                       (pipeline2(sol1_value,sol1A_value,sol1B_value+h,sol1AB_value)-pipeline2(sol1_value,sol1A_value,sol1B_value,sol1AB_value))/h,
                       (pipeline2(sol1_value,sol1A_value,sol1B_value,sol1AB_value+h)-pipeline2(sol1_value,sol1A_value,sol1B_value,sol1AB_value))/h])

该代码能生成4×4的偏导数矩阵,但代码冗长。我希望用approx_fprime替代,但它仅返回标量。请问如何用approx_fprime优雅地计算val1、val2、val3、val4对sol1、sol1A、sol1B、sol1AB的偏导数?

解决方案

approx_fprime仅支持标量输出的函数,可通过对pipeline2的每个输出分量单独求导,再组合成偏导数矩阵,以下是两种简洁实现方式:

方法一:循环遍历输出分量

对pipeline2返回数组的每个元素,定义仅返回该元素的函数,用approx_fprime计算该分量对输入参数的偏导数,最终堆叠为矩阵:

import numpy as np
from scipy.optimize import approx_fprime

# 输入参数基准值
sol_base = np.array([sol1_value, sol1A_value, sol1B_value, sol1AB_value])
h = 1e-10

# 初始化4×4雅可比矩阵
jacobian = np.zeros((4, 4))

for i in range(4):
    def partial_func(inp):
        return pipeline2(inp)[i]
    jacobian[i] = approx_fprime(sol_base, partial_func, h)

方法二:向量化批量处理

利用np.apply_along_axis批量处理所有输出分量,避免显式循环:

import numpy as np
from scipy.optimize import approx_fprime

sol_base = np.array([sol1_value, sol1A_value, sol1B_value, sol1AB_value])
h = 1e-10

jacobian = np.apply_along_axis(
    lambda i: approx_fprime(sol_base, lambda x: pipeline2(x)[i], h),
    axis=0,
    arr=np.arange(4)
)

关键说明

  • 两种方法生成的4×4雅可比矩阵中,jacobian[i][j]对应第i个输出(val1/val2/val3/val4)对第j个输入(sol1/sol1A/sol1B/sol1AB)的偏导数,与手动实现结果一致。
  • approx_fprime默认步长为1e-8,需显式传入h=1e-10以匹配手动实现的精度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:55:37