Python实现Householder变换报列表索引不能为元组TypeError错误
问题原因
你传入函数的A是Python原生嵌套列表,不支持A[行切片, 列索引]这种逗号分隔的多维索引写法,Python会把(k + 1) :, k识别为一个元组作为索引,所以触发类型错误。
解决方案
- 函数内部先将输入转换为numpy数组,保证支持多维索引操作
- 修正代码缩进问题:原代码中第二个
for l in ...循环及后续矩阵赋值代码,应缩进放在外层for k in ...循环内部,否则只会在k循环结束后执行一次,逻辑不符合Householder变换的迭代要求 - 给
householder函数添加返回值,否则最后打印new会得到None
修正后可运行代码
import numpy as np from numpy import array,identity,diagonal from math import sqrt,asin,acos,sin,cos,atan def householder(A): # 转换输入为numpy数组,支持多维索引 A = np.array(A, dtype=np.double) n = len(A) v = np.zeros(n, dtype=np.double) u = np.zeros(n, dtype=np.double) z = np.zeros(n, dtype=np.double) for k in range(0, n - 2): if np.isclose(A[k + 1][k], 0.0): α = -np.sqrt(np.sum(A[(k + 1) :, k] ** 2)) else: α = -np.sign(A[k + 1][k]) * np.sqrt(np.sum(A[(k + 1) :, k] ** 2)) two_r_squared = α ** 2 - α * A[k + 1][k] v[k] = 0.0 v[k + 1] = A[k + 1][k] - α v[(k + 2) :] = A[(k + 2) :, k] u[k:] = 1.0 / two_r_squared * np.dot(A[k:, (k + 1) :], v[(k + 1) :]) z[k:] = u[k:] - np.dot(u, v) / (2.0 * two_r_squared) * v[k:] # 以下逻辑移到k循环内部,保证每轮迭代都更新矩阵 for l in range(k + 1, n - 1): A[(l + 1) :, l] = ( A[(l + 1) :, l] - v[l] * z[(l + 1) :] - v[(l + 1) :] * z[l] ) A[l, (l + 1) :] = A[(l + 1) :, l] A[l, l] = A[l, l] - 2 * v[l] * z[l] A[-1, -1] = A[-1, -1] - 2 * v[-1] * z[-1] A[k, (k + 2) :] = 0.0 A[(k + 2) :, k] = 0.0 A[k + 1][k] = A[k + 1][k] - v[k + 1] * z[k] A[k][k + 1] = A[k + 1][k] return A A= [ [3,2,1,2] , [2,-1,1,2] , [1,1,4,30] , [2,2,3,1] ] new= householder(A) print(new)
内容的提问来源于stack exchange,提问作者Dries Gouws
相关产品推荐
相关产品推荐

