计算方法 python【类方法】 使用雅可比方法(吉文斯变换)Jacobi&Givens Transformation 求实对称矩阵的特征值

import math as mt
import  copy
class SquareMatrix():
    def __init__(self,a):
        self.A = self.ori = a
        self.n = len(a)
        self.trans = []
        self.Q = [[0]*self.n for i in range(self.n)]
        for i in range(self.n):
            self.Q[i][i] = 1


    def get_max(self):
        max = -1e9
        maxx = 0
        maxy = 0
        for i in range(self.n):
            for j in range(self.n):
                if i==j:
                    continue
                if abs(self.A[i][j])>max:
                    maxx = i
                    maxy= j
                    max = abs(self.A[i][j])
        return (max,maxx,maxy)

    def Jacobi_eigen(self,eps,iterN):

        _A = self.A
        count = 0
        while True:
            pos = self.get_max()
            if pos[0]iterN:
                break 
            Givens_trans_eliminate(self.A,pos[1],pos[2],self.Q)
            count +=1
        # print(self.A)
        # print(count)
        list = []
        for i in range(self.n):
            list.append(self.A[i][i])
        list.sort()
        for i in range(self.n ):
            print("%.2f"%list[i],end=" ")
    
def Givens_trans_eliminate(a,i,j,Q):
    b = (a[i][i]-a[j][j])/(2*a[i][j])
    t = 1/(abs(b)+mt.sqrt(1+b**2))
    if b<0:
        t = -t
    cos = 1/(mt.sqrt(1+t**2))
    sin = t/(mt.sqrt(1+t**2))

    olda = copy.deepcopy(a)
    for s in range(len(a)):
            if s!=i and s!=j:
                a[s][i] = a[i][s] = olda[s][i]*cos+olda[s][j]*sin
                a[s][j] = a[j][s] = -olda[s][i]*sin+olda[s][j]*cos
    a[i][i] = olda[i][i]*cos*cos +2*olda[i][j]*cos*sin+olda[j][j]*sin*sin
    a[j][j] = olda[i][i]*sin*sin-2*olda[i][j]*cos*sin+olda[j][j]*cos*cos
    a[i][j] = a[j][i] = 0

    oldq = copy.deepcopy(Q)
    for s in range(len(a)):
            # Q[s][i] = Q[s][i]*cos+Q[s][j]*sin
            # Q[s][j] = -Q[s][i]*sin+Q[s][j]*cos

            Q[s][i] = oldq[s][i] * cos + oldq[s][j] * sin
            Q[s][j] = -oldq[s][i] * sin + oldq[s][j] * cos


def _getMatrix():
    matrix = []
    row = []
    for i in range(3):
        inp = input().split(' ')
        row = [float(inp[num]) for num in range(len(inp)) ]
        matrix.append(row)
    return matrix

a = _getMatrix()
s = SquareMatrix(a)
inp = input().split(' ')
eps = float(inp[1])
itern = float(inp[0])
s.Jacobi_eigen(eps,itern)

 

你可能感兴趣的:(Python)