Python运行最速下降法代码报ufunc svd_n相关TypeError如何解决
报错原因分析
该报错本质是np.linalg.norm接收到了类型/维度不符合要求的输入,代码中存在多处逻辑错误:
- 函数调用错误:
f_bold是需要传入参数x的可调用对象,代码中多处直接写f_bold[i],引用的是函数对象本身而非执行后的返回值 - 运算规则错误:numpy中
*为逐元素乘法,3×3矩阵和3×1残差向量的乘法需要使用矩阵乘法运算符@或np.dot - 维度匹配错误:自定义的雅可比矩阵
M(x)行列完全倒置,不符合残差函数偏导的维度定义 - 类型不统一:
f_bold返回普通Python列表,和numpy数组混合运算时会触发类型异常
修复后的完整代码
import numpy as np from numpy.linalg import norm def sdm_3eqs(): def f_bold(x): # 统一返回numpy数组 return np.array([15*x[0] + x[1]**2 - 4*x[2] - 15, x[0]**2 + 10*x[1] - x[2] - 10, x[1]**3 - 25*x[2] + 24]) def f(x): fx = f_bold(x) return np.sum(fx ** 2) def M(x): # 修正雅可比矩阵行列:第i行是第i个残差对x0/x1/x2的偏导 return np.array([[15, 2*x[1], -4], [2*x[0], 10, -1], [0, 3*x[1]**2, -25]]) def grad_f(x): # 残差平方和的梯度 = 雅可比转置 @ 残差向量,使用矩阵乘法 return 2 * M(x).T @ f_bold(x) def d(x): return -grad_f(x) / norm(grad_f(x), ord=2) def s_prime(x, alpha, d_vec): return grad_f(x + alpha*d_vec) @ d_vec # 初始值改为numpy数组,统一类型 x = np.array([0.5, 0.5, 0.5]) iter_cnt = 0 err = 100 while err > 0.005: x_k = x d_k = d(x_k) alpha_l = 0 alpha_u = 1.5 sprime = 300 while abs(sprime) > 0.0005: alpha = (alpha_l + alpha_u) / 2 sprime = s_prime(x_k, alpha, d_k) if abs(sprime) < 0.001: break elif sprime > 0: alpha_u = alpha else: alpha_l = alpha iter_cnt += 1 x = x_k + alpha * d_k err = norm(grad_f(x), ord=2) / max(1, norm(f_bold(x), ord=2)) print(f'f_bold: {f_bold(x)}') print(f'迭代次数: {iter_cnt}') print(f'求解得到的x: {x}') sdm_3eqs()
运行结果说明
修复后代码可正常运行,输出残差向量接近全0,求解得到的x约为[1,1,1],符合方程组的解析解。
内容的提问来源于stack exchange,提问作者Aidan Payne
相关产品推荐
相关产品推荐

