调用psi函数时为何出现'numpy.ndarray object not callable'错误?
问题定位与解决方案
首先,触发TypeError: 'numpy.ndarray' object is not callable的核心原因是参数命名冲突+对传入值的错误使用,咱们一步步拆解:
1. 错误根源分析
你调用psi(1.0, lowest_eigenvectors(100, 4, 0.1), 0)时,第二个参数传入的是lowest_eigenvectors()函数执行后的结果——一个numpy.ndarray数组。但在psi函数内部,你写了:
herm_coeffs = [element*N_coeff(i) for element in lowest_eigenvectors(N, n, lam)[i]]
这里的lowest_eigenvectors已经不是原来的函数了,而是你传入的数组!数组是不能像函数那样加括号调用的,这就直接触发了"object is not callable"错误。
另外还有两个隐藏问题:
psi函数里的N、n、lam都是未定义的变量,即使解决了上面的问题,也会触发NameError。- 谐振子波函数的指数部分符号错误:应该是
np.exp(-x**2/2.0),你写的正号会导致波函数随x增大无限发散,不符合物理意义。
2. 修复步骤与修正后的代码
步骤1:修改psi函数的参数与逻辑
把参数名从lowest_eigenvectors改成eigenvecs(避免和函数名重名),直接使用传入的数组,不需要再调用函数。
步骤2:优化lowest_eigenvectors函数
原函数多次重复调用eigh(),效率极低,而且误用了未导入的eig(),改成先一次性计算特征值和特征向量,再筛选。
完整修正代码
import numpy as np import math from numpy.linalg import eigh from numpy.polynomial.hermite import hermval def matrices(N, lam): H_0 = np.zeros([N+1, N+1]) x_four_matrix = np.zeros([N+1, N+1]) for n in range(N+1): for m in range(N+1): if n == m: H_0[n][m] = n + 0.5 x_four_matrix[n][m] = (6.0*n**2 + 6.0*n + 3.0)/4.0 elif n == m-2: x_four_matrix[n][m] = np.sqrt((n+1)*(n+2))*(n+1.5) elif n == m+2: x_four_matrix[n][m] = (n-0.5)*np.sqrt(n*(n-1)) elif n == m-4: x_four_matrix[n][m] = np.sqrt((n+1)*(n+2)*(n+3)*(n+4))/4.0 elif n == m+4: x_four_matrix[n][m] = np.sqrt((n-3)*(n-2)*(n-1)*n)/4.0 return H_0, x_four_matrix def H_lam(N, lam): return matrices(N, lam)[0] + lam*matrices(N, lam)[1] # Solve for eigenvalues (energies) def lowest_eigenvals(N, n, lam): eigenvals = eigh(H_lam(N, lam))[0] eigenvals.sort() return eigenvals[:n] # 简化切片操作 # Solve for eigenvectors def lowest_eigenvectors(N, n, lam): # 只计算一次特征值和特征向量,提升效率 eigenvals, eigenvecs = eigh(H_lam(N, lam)) # 获取最小n个特征值的索引 idx = eigenvals.argsort()[:n] # 返回对应的特征向量 return eigenvecs[:, idx].T # 转置后和原逻辑一致,每行对应一个特征向量 def N_coeff(i): return 1.0/np.sqrt(2**i*math.factorial(i)*np.sqrt(np.pi)) # 修正后的psi函数 def psi(x, eigenvecs, i): # 直接使用传入的特征向量数组,不需要再调用函数 herm_coeffs = [element * N_coeff(k) for k, element in enumerate(eigenvecs[i])] # 修正指数符号为负 return np.exp(-x**2 / 2.0) * hermval(x, herm_coeffs) # 测试代码 print([element*N_coeff(0) for element in lowest_eigenvectors(100, 4, 0.1)[0]]) print(psi(1.0, lowest_eigenvectors(100, 4, 0.1), 0))
3. 额外说明
- 修正后的
lowest_eigenvectors用argsort()获取排序后的索引,一次性筛选出最小n个特征向量,比原逻辑高效得多。 psi函数里的herm_coeffs循环中,用enumerate获取厄米多项式的阶数k,对应N_coeff(k),这才是正确的归一化系数对应关系(原代码里固定用i是错误的,因为特征向量的每个元素对应不同阶的厄米多项式系数)。
内容的提问来源于stack exchange,提问作者curious_cosmo
相关产品推荐
相关产品推荐

