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

使用Numpy求解振子链本征向量结果异常的问题排查

振子链本征向量求解与绘制问题排查

问题描述

我尝试用Python的Numpy库求解并绘制振子链(弹簧)的本征向量,但结果和预期不符:运行代码得到的第一本征向量存在负值,而正确的第一本征向量(对应整体平移模式)应该全为非负值。

原代码

import numpy as np
import matplotlib.pyplot as plt

def matrix_creation(dimension,h,k,l):
    #This function creates the tridiagonal matrix

    matrix=np.zeros((dimension,dimension)) #this specifies the size of the rows and columns


    matrix[0][0]=h
    matrix[0][1]=k
    matrix[dimension-1][dimension-1]=l
    matrix[dimension-1][dimension-2]=k

    for j in range(1,dimension-1):
        matrix[j][j-1]=h
        matrix[j][j]=k
        matrix[j][j+1]=l

    return matrix


def plot_eigenvectors(rest_position, eigenvectors, N):
    # Plot each eigenvector
    for i in range(4):
        plt.plot(rest_position, eigenvectors[:,i], label=f'Eigenvector {i+1}')
        plt.title('Eigenvectors at time t=0')
        plt.xlabel('Rest Position (x)')
        plt.ylabel('Eigenvector Value (y)')
        plt.legend()
        plt.grid(True)
        plt.show()
     


def main():
    N=50
    spring_tension=4
    mass=1
    h=-spring_tension/mass
    k=2*spring_tension/mass
    l=h


    matrix=matrix_creation(N,h,k,l)
    #print(np.linalg.eigvals(matrix))
    #to acces al the information we can use the following comand
    eigenvalues,eigenvectors=np.linalg.eig(matrix)
    rest_position=[a for a in range(1,N+1)]
    #plot_eigenvectors(rest_position,eigenvectors,N)

if __name__=="__main__":
    main()

问题排查与修正

1. 矩阵构造完全颠倒

振子链的动力学矩阵(描述每个振子受力的矩阵)是三对角矩阵,正确的赋值逻辑为:

  • 对角元:每个振子受左右两个弹簧的拉力,值为 2*spring_tension/mass(即你的变量k)
  • 次对角元(上下相邻位置):每个振子受相邻振子的拉力,值为 -spring_tension/mass(即你的变量h)

原代码把对角元和次对角元的赋值完全搞反了,修正后的matrix_creation函数:

def matrix_creation(dimension,h,k,l):
    matrix=np.zeros((dimension,dimension))
    # 第一行:仅右邻居,对角元为k,次对角元为h
    matrix[0][0]=k
    matrix[0][1]=h
    # 最后一行:仅左邻居,对角元为k,次对角元为h
    matrix[dimension-1][dimension-1]=k
    matrix[dimension-1][dimension-2]=h
    # 中间行:左右均有邻居
    for j in range(1,dimension-1):
        matrix[j][j-1]=h
        matrix[j][j]=k
        matrix[j][j+1]=h
    return matrix

2. 本征值与本征向量未排序

np.linalg.eig返回的结果是无序的,默认不会按本征值从小到大排列。振子链的最低本征值(对应整体平移模式)才会对应全同符号的本征向量,需要先对本征值排序,再重新排列本征向量:

# 获取本征值排序后的索引
sorted_indices = np.argsort(eigenvalues)
# 按索引重新排列本征值和本征向量
sorted_eigenvalues = eigenvalues[sorted_indices]
sorted_eigenvectors = eigenvectors[:, sorted_indices]

3. 本征向量符号处理

本征向量的符号是任意的(若v是本征向量,则-v也是同一本征值的本征向量)。如果排序后的本征向量是全负的,只需乘以-1即可匹配预期的非负模式:

# 确保每个本征向量的首元素为正
for i in range(sorted_eigenvectors.shape[1]):
    if sorted_eigenvectors[0, i] < 0:
        sorted_eigenvectors[:, i] *= -1

修正后的完整代码

import numpy as np
import matplotlib.pyplot as plt

def matrix_creation(dimension,h,k,l):
    matrix=np.zeros((dimension,dimension))
    # 第一行
    matrix[0][0]=k
    matrix[0][1]=h
    # 最后一行
    matrix[dimension-1][dimension-1]=k
    matrix[dimension-1][dimension-2]=h
    # 中间行
    for j in range(1,dimension-1):
        matrix[j][j-1]=h
        matrix[j][j]=k
        matrix[j][j+1]=h
    return matrix


def plot_eigenvectors(rest_position, eigenvectors, N):
    for i in range(4):
        plt.plot(rest_position, eigenvectors[:,i], label=f'Eigenvector {i+1}')
        plt.title('Eigenvectors at time t=0')
        plt.xlabel('Rest Position (x)')
        plt.ylabel('Eigenvector Value (y)')
        plt.legend()
        plt.grid(True)
        plt.show()
     


def main():
    N=50
    spring_tension=4
    mass=1
    h=-spring_tension/mass
    k=2*spring_tension/mass
    l=h

    matrix=matrix_creation(N,h,k,l)
    eigenvalues,eigenvectors=np.linalg.eig(matrix)
    
    # 排序本征值与本征向量
    sorted_indices = np.argsort(eigenvalues)
    sorted_eigenvectors = eigenvectors[:, sorted_indices]
    
    # 修正本征向量符号
    for i in range(sorted_eigenvectors.shape[1]):
        if sorted_eigenvectors[0, i] < 0:
            sorted_eigenvectors[:, i] *= -1
    
    rest_position=[a for a in range(1,N+1)]
    plot_eigenvectors(rest_position,sorted_eigenvectors,N)

if __name__=="__main__":
    main()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:10:16