-
Notifications
You must be signed in to change notification settings - Fork 44
/
MatrixEigenJacobiPass.go
96 lines (91 loc) · 3.27 KB
/
MatrixEigenJacobiPass.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// MatrixEigenJacobiPass
/*
------------------------------------------------------
作者 : Black Ghost
日期 : 2018-11-30
版本 : 0.0.0
------------------------------------------------------
求解n阶对称矩阵A的全部特征值及其特征向量,雅可比过关法
理论:
参考 李信真, 车刚明, 欧阳洁, 等. 计算方法. 西北工业大学
出版社, 2000, pp 90.
------------------------------------------------------
输入 :
A 系数矩阵
tol 最大容许误差
n 最大迭代步数
输出 :
Bbar 主特征值矩阵(n阶对角矩阵)
Rbar 主特征值所对应的特征向量(n维矩阵,第i列即对应于
第i个特征值的特征向量)
(err) 解出标志:false-未解出或达到步数上限;
true-全部解出
------------------------------------------------------
*/
package goNum
// MatrixEigenJacobiPass 求解n阶对称矩阵A的全部特征值及其特征向量,雅可比过关法
func MatrixEigenJacobiPass(A Matrix, tol float64, n int) (Matrix, Matrix, bool) {
/*
求解n阶对称矩阵A的全部特征值及其特征向量,雅可比过关法
输入 :
A 系数矩阵
tol 最大容许误差
n 最大迭代步数
输出 :
Bbar 主特征值矩阵(n阶对角矩阵)
Rbar 主特征值所对应的特征向量(n维矩阵,第i列即对应于
第i个特征值的特征向量)
(err) 解出标志:false-未解出或达到步数上限;
true-全部解出
*/
//判断A是否对称矩阵
if !isSymMatrix_MatrixEigenClassicalJacobi(A) {
return ZeroMatrix(A.Rows, A.Columns), ZeroMatrix(A.Rows, A.Columns), false
}
//1.
//Rbar最终为特征向量矩阵
Rbar := IdentityE(A.Rows)
//复制A矩阵为B,B为迭代过程中逐渐改变的矩阵,最终将成为特征值矩阵
B := ZeroMatrix(A.Rows, A.Columns)
Bbar := ZeroMatrix(A.Rows, A.Columns)
for i := 0; i < len(A.Data); i++ {
B.Data[i] = A.Data[i]
}
//2. 计算非对角元素平方和
v0 := sum2Else_MatrixEigenClassicalJacobi(B)
//3. 设置阀值v1
v1 := v0 / float64(B.Rows)
//迭代步
for i := 0; i < n; i++ {
for i0 := 0; i0 < B.Rows-1; i0++ {
for j := i + 1; j < B.Columns; j++ {
//逐个扫描,判断是否大于阀值
if B.GetFromMatrix(i, j) > v1 {
//Jocobi正交相似变换(古典Jocobi法)
//计算cos(theta)及sin(theta)
cost, sint := cosSinTheta_MatrixEigenClassicalJacobi(B, i, j)
//R为迭代矩阵
R := IdentityE(A.Rows)
R.SetMatrix(i, i, cost)
R.SetMatrix(i, j, sint)
R.SetMatrix(j, i, -1.0*sint)
R.SetMatrix(j, j, cost)
Bbar = DotPruduct(DotPruduct(R, B), R.Transpose()) //A1 = RARt
//Rbar = Rbar*Rt
Rbar = DotPruduct(Rbar, R.Transpose())
}
}
}
//计算并判断v1是否满足误差需求,否则迭代
v0 = sum2Else_MatrixEigenClassicalJacobi(Bbar)
if v0 < tol {
return Bbar, Rbar, true
}
v1 = v0 / float64(B.Rows)
//A = A1
for i := 0; i < len(Bbar.Data); i++ {
B.Data[i] = Bbar.Data[i]
}
}
return ZeroMatrix(A.Rows, A.Columns), ZeroMatrix(A.Rows, A.Columns), false
}